Ejemplo n.º 1
0
    def test_001_two_johns(self):
        from tests.functional.user_add import user_add
        user_add("John", "Doe")
        user_add("John", "Doe")

        time.sleep(3)

        auth = Auth()
        auth.connect()

        max_tries = 20
        while max_tries > 0:
            recipient1 = auth.find_recipient('*****@*****.**')
            recipient2 = auth.find_recipient('*****@*****.**')

            if not recipient1 or not recipient2:
                time.sleep(1)
                max_tries -= 1
            else:
                break

        imap = IMAP()
        imap.connect()

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1, "No INBOX found for first John")

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1, "No INBOX found for second John")
Ejemplo n.º 2
0
    def test_001_two_johns(self):
        from tests.functional.user_add import user_add
        user_add("John", "Doe")
        user_add("John", "Doe")

        time.sleep(3)

        auth = Auth()
        auth.connect()

        max_tries = 20
        while max_tries > 0:
            recipient1 = auth.find_recipient('*****@*****.**')
            recipient2 = auth.find_recipient('*****@*****.**')

            if not recipient1 or not recipient2:
                time.sleep(1)
                max_tries -= 1
            else:
                break

        imap = IMAP()
        imap.connect()

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1, "No INBOX found for first John")

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1, "No INBOX found for second John")
Ejemplo n.º 3
0
    def test_001_user_rename(self):
        """
            Rename user "Doe, John" to "Sixpack, Joe" and verify the recipient
            policy is applied, and the IMAP INBOX folder for the user is
            renamed.
        """
        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient('*****@*****.**')
        user_info = wap_client.user_info(recipient)

        if 'mailhost' not in user_info:
            from tests.functional.synchronize import synchronize_once
            synchronize_once()

        imap = IMAP()
        imap.connect()
        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1)

        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (self.user))

        user_info = wap_client.user_info(recipient)
        user_info['sn'] = 'Sixpack'
        user_info['givenname'] = 'Joe'
        user_info['uid'] = 'sixpack'
        user_edit = wap_client.user_edit(recipient, user_info)

        time.sleep(2)

        print imap.lm()

        user_info = wap_client.user_info('uid=sixpack,ou=People,dc=example,dc=org')
        if not user_info['mail'] == '*****@*****.**':
            from tests.functional.synchronize import synchronize_once
            synchronize_once()
            user_info = wap_client.user_info('uid=sixpack,ou=People,dc=example,dc=org')

        self.assertEqual(user_info['mail'], '*****@*****.**')

        print imap.lm()

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 0, "INBOX for john.doe still exists")

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1, "INBOX for joe.sixpack does not exist")
Ejemplo n.º 4
0
    def test_001_user_rename(self):
        """
            Rename user "Doe, John" to "Sixpack, Joe" and verify the recipient
            policy is applied, and the IMAP INBOX folder for the user is
            renamed.
        """
        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient('*****@*****.**')
        user_info = wap_client.user_info(recipient)

        if not user_info.has_key('mailhost'):
            from tests.functional.synchronize import synchronize_once
            synchronize_once()

        imap = IMAP()
        imap.connect()
        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1)

        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (self.user))

        user_info = wap_client.user_info(recipient)
        user_info['sn'] = 'Sixpack'
        user_info['givenname'] = 'Joe'
        user_info['uid'] = 'sixpack'
        user_edit = wap_client.user_edit(recipient, user_info)

        time.sleep(2)

        print imap.lm()

        user_info = wap_client.user_info('uid=sixpack,ou=People,dc=example,dc=org')
        if not user_info['mail'] == '*****@*****.**':
            from tests.functional.synchronize import synchronize_once
            synchronize_once()
            user_info = wap_client.user_info('uid=sixpack,ou=People,dc=example,dc=org')

        self.assertEqual(user_info['mail'], '*****@*****.**')

        print imap.lm()

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 0, "INBOX for john.doe still exists")

        folders = imap.lm('user/[email protected]')
        self.assertEqual(len(folders), 1, "INBOX for joe.sixpack does not exist")
Ejemplo n.º 5
0
    def test_002_user_recipient_policy_duplicate(self):
        from tests.functional.user_add import user_add
        user = {
                'local': 'jane.doe',
                'domain': 'example.org'
            }
        user_add("Jane", "Doe")

        time.sleep(3)

        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (user))
        if hasattr(self, 'assertIsInstance'):
            self.assertIsInstance(recipient, str)

        self.assertEqual(recipient, "uid=doe2,ou=People,dc=example,dc=org")

        result = wap_client.user_info(recipient)

        if not result.has_key('mailhost'):
            from tests.functional.synchronize import synchronize_once
            synchronize_once()

        result = wap_client.user_info(recipient)

        self.assertEqual(result['mail'], '*****@*****.**')
        self.assertEqual(result['alias'], ['*****@*****.**', '*****@*****.**'])
Ejemplo n.º 6
0
    def test_002_user_recipient_policy_duplicate(self):
        from tests.functional.user_add import user_add
        user = {'local': 'jane.doe', 'domain': 'example.org'}
        user_add("Jane", "Doe")

        time.sleep(3)

        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (user))
        if hasattr(self, 'assertIsInstance'):
            self.assertIsInstance(recipient, str)

        self.assertEqual(recipient, "uid=doe2,ou=People,dc=example,dc=org")

        result = wap_client.user_info(recipient)

        if 'mailhost' not in result:
            from tests.functional.synchronize import synchronize_once
            synchronize_once()

        result = wap_client.user_info(recipient)

        self.assertEqual(result['mail'], '*****@*****.**')
        self.assertEqual(result['alias'],
                         ['*****@*****.**', '*****@*****.**'])
Ejemplo n.º 7
0
def execute(*args, **kw):
    """
        Transfer mailbox
    """

    if len(conf.cli_args) > 1:
        mailfolder = conf.cli_args.pop(0)
        target_server = conf.cli_args.pop(0)

    if len(conf.cli_args) > 0:
        target_partition = conf.cli_args.pop(0)

    imap = IMAP()
    imap.connect()

    mbox_parts = imap.parse_mailfolder(mailfolder)

    if mbox_parts['domain'] == None:
        domain = conf.get('kolab', 'primary_domain')
        user_identifier = mbox_parts['path_parts'][1]
    else:
        domain = mbox_parts['domain']
        user_identifier = "%s@%s" % (mbox_parts['path_parts'][1], mbox_parts['domain'])

    auth = Auth(domain=domain)
    auth.connect()

    user = auth.find_recipient(user_identifier)

    source_server = imap.user_mailbox_server(mailfolder)
    imap.connect(server=source_server)
    imap.imap.xfer(mailfolder, target_server)

    if not user == None and not len(user) < 1:
        auth.set_entry_attributes(domain, user, {'mailhost': target_server})
Ejemplo n.º 8
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    script_to_put = conf.cli_args.pop(0)
    
    script_put_name = conf.cli_args.pop(0)

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve
 
    sieveclient = sievelib.managesieve.Client(hostname, port, False)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    sieveclient.putscript(script_put_name, open(script_to_put, "r").read())
Ejemplo n.º 9
0
    def test_001_user_recipient_policy(self):
        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (self.user))
        if hasattr(self, 'assertIsInstance'):
            self.assertIsInstance(recipient, str)

        self.assertEqual(recipient, "uid=doe,ou=People,dc=example,dc=org")

        result = wap_client.user_info(recipient)

        self.assertEqual(result['mail'], '*****@*****.**')
        self.assertEqual(result['alias'], ['*****@*****.**', '*****@*****.**'])
Ejemplo n.º 10
0
    def test_002_fr_FR_user_recipient_policy(self):
        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (self.user))
        if hasattr(self, 'assertIsInstance'):
            self.assertIsInstance(recipient, str)

        self.assertEqual(recipient, "uid=fuentes,ou=People,dc=example,dc=org")

        result = wap_client.user_info(recipient)

        self.assertEqual(result['mail'], '*****@*****.**')
        self.assertEqual(sorted(result['alias']), ['*****@*****.**', '*****@*****.**'])
Ejemplo n.º 11
0
    def test_001_user_recipient_policy(self):
        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (self.user))
        if hasattr(self, 'assertIsInstance'):
            self.assertIsInstance(recipient, str)

        self.assertEqual(recipient, "uid=doe,ou=People,dc=example,dc=org")

        result = wap_client.user_info(recipient)

        self.assertEqual(result['mail'], '*****@*****.**')
        self.assertEqual(result['alias'],
                         ['*****@*****.**', '*****@*****.**'])
Ejemplo n.º 12
0
    def test_002_fr_FR_user_recipient_policy(self):
        auth = Auth()
        auth.connect()
        recipient = auth.find_recipient("%(local)s@%(domain)s" % (self.user))
        if hasattr(self, 'assertIsInstance'):
            self.assertIsInstance(recipient, str)

        self.assertEqual(recipient, "uid=fuentes,ou=People,dc=example,dc=org")

        result = wap_client.user_info(recipient)

        self.assertEqual(result['mail'], '*****@*****.**')
        self.assertEqual(sorted(result['alias']),
                         ['*****@*****.**', '*****@*****.**'])
Ejemplo n.º 13
0
    def test_001_default(self):
        from tests.functional.user_add import user_add
        user_add("John", "Doe")
        from tests.functional.synchronize import synchronize_once
        synchronize_once()

        auth = Auth()
        auth.connect()

        user = auth.find_recipient('*****@*****.**')

        user_info = wap_client.user_info(user)

        self.assertEqual(user_info['uid'], "doe")

        from tests.functional.purge_users import purge_users
        purge_users()
Ejemplo n.º 14
0
    def test_001_default(self):
        from tests.functional.user_add import user_add
        user_add("John", "Doe")
        from tests.functional.synchronize import synchronize_once
        synchronize_once()

        auth = Auth()
        auth.connect()

        user = auth.find_recipient('*****@*****.**')

        user_info = wap_client.user_info(user)

        self.assertEqual(user_info['uid'], "doe")

        from tests.functional.purge_users import purge_users
        purge_users()
Ejemplo n.º 15
0
    def test_003_givenname_fc_dot_surname(self):
        self.set('example.org', 'policy_uid', "'%(givenname)s'[0:1].%(surname)s")

        from tests.functional.user_add import user_add
        user_add("John", "Doe")
        from tests.functional.synchronize import synchronize_once
        synchronize_once()

        auth = Auth()
        auth.connect()

        user = auth.find_recipient('*****@*****.**')

        user_info = wap_client.user_info(user)

        self.assertEqual(user_info['uid'], "J.Doe")

        from tests.functional.purge_users import purge_users
        purge_users()
Ejemplo n.º 16
0
    def test_003_givenname_fc_dot_surname(self):
        self.set('example.org', 'policy_uid', "'%(givenname)s'[0:1].%(surname)s")

        from tests.functional.user_add import user_add
        user_add("John", "Doe")
        from tests.functional.synchronize import synchronize_once
        synchronize_once()

        auth = Auth()
        auth.connect()

        user = auth.find_recipient('*****@*****.**')

        user_info = wap_client.user_info(user)

        self.assertEqual(user_info['uid'], "J.Doe")

        from tests.functional.purge_users import purge_users
        purge_users()
Ejemplo n.º 17
0
def execute(*args, **kw):
    """
        Transfer mailbox
    """

    if len(conf.cli_args) > 1:
        mailfolder = conf.cli_args.pop(0)
        target_server = conf.cli_args.pop(0)

    if len(conf.cli_args) > 0:
        target_partition = conf.cli_args.pop(0)

    imap = IMAP()
    imap.connect()

    mbox_parts = imap.parse_mailfolder(mailfolder)

    if mbox_parts['domain'] == None:
        domain = conf.get('kolab', 'primary_domain')
        user_identifier = mbox_parts['path_parts'][1]
    else:
        domain = mbox_parts['domain']
        user_identifier = "%s@%s" % (mbox_parts['path_parts'][1],
                                     mbox_parts['domain'])

    auth = Auth(domain=domain)
    auth.connect()

    user = auth.find_recipient(user_identifier)

    source_server = imap.user_mailbox_server(mailfolder)
    imap.connect(server=source_server)
    imap.imap.xfer(mailfolder, target_server)

    if not user == None and not len(user) < 1:
        auth.set_entry_attributes(domain, user, {'mailhost': target_server})
Ejemplo n.º 18
0
        folders = []

        folders.extend(imap.lm('shared/%%@%s' % (primary)))
        folders.extend(imap.lm('user/%%@%s' % (primary)))

        for secondary in secondaries:
            folders.extend(imap.lm('shared/%%@%s' % (secondary)))
            folders.extend(imap.lm('user/%%@%s' % (secondary)))

        auth = Auth(domain=primary)
        auth.connect()

        for folder in folders:
            server = imap.user_mailbox_server(folder)
            recipient = auth.find_recipient('/'.join(folder.split('/')[1:]))
            if (isinstance(recipient, list)):
                if len(recipient) > 1:
                    log.warning(_("Multiple recipients for '%s'!") % ('/'.join(folder.split('/')[1:])))
                    continue
                elif len(recipient) == 0:
                    if conf.delete:
                        if conf.dry_run:
                            if not folder.split('/')[0] == 'shared':
                                log.warning(_("No recipients for '%s' (would have deleted the mailbox if not for --dry-run)!") % ('/'.join(folder.split('/')[1:])))
                            else:
                                continue
                        else:
                            if not '/'.join(folder.split('/')[0]) == 'shared':
                                log.info(_("Deleting mailbox '%s' because it has no recipients") % (folder))
                                try:
Ejemplo n.º 19
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port,
                                              conf.debuglevel > 8)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    result = sieveclient.listscripts()

    if result == None:
        active = None
        scripts = []
    else:
        active, scripts = result

    log.debug(_("Found the following scripts for user %s: %s") %
              (address, ','.join(scripts)),
              level=8)
    log.debug(_("And the following script is active for user %s: %s") %
              (address, active),
              level=8)

    mgmt_required_extensions = []

    mgmt_script = """#
# MANAGEMENT
#
"""

    user = auth.get_entry_attributes(domain, user, ['*'])

    #
    # Vacation settings (a.k.a. Out of Office)
    #
    vacation_active = None
    vacation_text = None
    vacation_uce = None
    vacation_noreact_domains = None
    vacation_react_domains = None

    vacation_active_attr = conf.get('sieve', 'vacation_active_attr')
    vacation_text_attr = conf.get('sieve', 'vacation_text_attr')
    vacation_uce_attr = conf.get('sieve', 'vacation_uce_attr')
    vacation_noreact_domains_attr = conf.get('sieve',
                                             'vacation_noreact_domains_attr')
    vacation_react_domains_attr = conf.get('sieve',
                                           'vacation_react_domains_attr')

    if not vacation_text_attr == None:

        if user.has_key(vacation_active_attr):
            vacation_active = utils.true_or_false(user[vacation_active_attr])
        else:
            vacation_active = False

        if user.has_key(vacation_text_attr):
            vacation_text = user[vacation_text_attr]
        else:
            vacation_active = False

        if user.has_key(vacation_uce_attr):
            vacation_uce = utils.true_or_false(user[vacation_uce_attr])
        else:
            vacation_uce = False

        if user.has_key(vacation_react_domains_attr):
            if isinstance(user[vacation_react_domains_attr], list):
                vacation_react_domains = user[vacation_react_domains_attr]
            else:
                vacation_react_domains = [user[vacation_react_domains_attr]]
        else:
            if user.has_key(vacation_noreact_domains_attr):
                if isinstance(user[vacation_noreact_domains_attr], list):
                    vacation_noreact_domains = user[
                        vacation_noreact_domains_attr]
                else:
                    vacation_noreact_domains = [
                        user[vacation_noreact_domains_attr]
                    ]
            else:
                vacation_noreact_domains = []

    #
    # Delivery to Folder
    #
    dtf_active_attr = conf.get('sieve', 'deliver_to_folder_active')
    if not dtf_active_attr == None:
        if user.has_key(dtf_active_attr):
            dtf_active = utils.true_or_false(user[dtf_active_attr])
        else:
            dtf_active = False
    else:
        # TODO: Not necessarily de-activated, the *Active attributes are
        # not supposed to charge this - check the deliver_to_folder_attr
        # attribute value for a value.
        dtf_active = False

    if dtf_active:
        dtf_folder_name_attr = conf.get('sieve', 'deliver_to_folder_attr')
        if not dtf_folder_name_attr == None:
            if user.has_key(dtf_folder_name_attr):
                dtf_folder = user[dtf_folder_name_attr]
            else:
                log.warning(
                    _("Delivery to folder active, but no folder name attribute available for user %r"
                      ) % (user))
                dtf_active = False
        else:
            log.error(
                _("Delivery to folder active, but no folder name attribute configured"
                  ))
            dtf_active = False

    #
    # Folder name to delivery spam to.
    #
    # Global or local.
    #
    sdf_filter = True
    sdf = conf.get('sieve', 'spam_global_folder')

    if sdf == None:
        sdf = conf.get('sieve', 'spam_personal_folder')
        if sdf == None:
            sdf_filter = False

    #
    # Mail forwarding
    #
    forward_active = None
    forward_addresses = []
    forward_keepcopy = None
    forward_uce = None

    forward_active_attr = conf.get('sieve', 'forward_address_active')
    if not forward_active_attr == None:
        if user.has_key(forward_active_attr):
            forward_active = utils.true_or_false(user[forward_active_attr])
        else:
            forward_active = False

    if not forward_active == False:
        forward_address_attr = conf.get('sieve', 'forward_address_attr')
        if user.has_key(forward_address_attr):
            if isinstance(user[forward_address_attr], basestring):
                forward_addresses = [user[forward_address_attr]]
            elif isinstance(user[forward_address_attr], str):
                forward_addresses = [user[forward_address_attr]]
            else:
                forward_addresses = user[forward_address_attr]

        if len(forward_addresses) == 0:
            forward_active = False

        forward_keepcopy_attr = conf.get('sieve', 'forward_keepcopy_active')
        if not forward_keepcopy_attr == None:
            if user.has_key(forward_keepcopy_attr):
                forward_keepcopy = utils.true_or_false(
                    user[forward_keepcopy_attr])
            else:
                forward_keepcopy = False

        forward_uce_attr = conf.get('sieve', 'forward_uce_active')
        if not forward_uce_attr == None:
            if user.has_key(forward_uce_attr):
                forward_uce = utils.true_or_false(user[forward_uce_attr])
            else:
                forward_uce = False

    if vacation_active:
        mgmt_required_extensions.append('vacation')
        mgmt_required_extensions.append('envelope')

    if dtf_active:
        mgmt_required_extensions.append('fileinto')

    if forward_active and (len(forward_addresses) > 1 or forward_keepcopy):
        mgmt_required_extensions.append('copy')

    if sdf_filter:
        mgmt_required_extensions.append('fileinto')

    import sievelib.factory

    mgmt_script = sievelib.factory.FiltersSet("MANAGEMENT")

    for required_extension in mgmt_required_extensions:
        mgmt_script.require(required_extension)

    mgmt_script.require('fileinto')

    if vacation_active:
        if not vacation_react_domains == None and len(
                vacation_react_domains) > 0:
            mgmt_script.addfilter(
                'vacation',
                [('envelope', ':domain', ":is", "from", vacation_react_domains)
                 ],
                [(
                    "vacation",
                    ":days",
                    1,
                    ":subject",
                    "Out of Office",
                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                    # ":mime", to indicate the reason is in fact MIME
                    vacation_text)])

        elif not vacation_noreact_domains == None and len(
                vacation_noreact_domains) > 0:
            mgmt_script.addfilter(
                'vacation',
                [('not', ('envelope', ':domain', ":is", "from",
                          vacation_noreact_domains))],
                [(
                    "vacation",
                    ":days",
                    1,
                    ":subject",
                    "Out of Office",
                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                    # ":mime", to indicate the reason is in fact MIME
                    vacation_text)])

        else:
            mgmt_script.addfilter(
                'vacation',
                [('true', )],
                [(
                    "vacation",
                    ":days",
                    1,
                    ":subject",
                    "Out of Office",
                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                    # ":mime", to indicate the reason is in fact MIME
                    vacation_text)])

    if forward_active:
        forward_rules = []

        # Principle can be demonstrated by:
        #
        # python -c "print ','.join(['a','b','c'][:-1])"
        #
        for forward_copy in forward_addresses[:-1]:
            forward_rules.append(("redirect", ":copy", forward_copy))

        if forward_keepcopy:
            # Principle can be demonstrated by:
            #
            # python -c "print ','.join(['a','b','c'][-1])"
            #
            if forward_uce:
                rule_name = 'forward-uce-keepcopy'
            else:
                rule_name = 'forward-keepcopy'

            forward_rules.append(("redirect", ":copy", forward_addresses[-1]))
        else:
            if forward_uce:
                rule_name = 'forward-uce'
            else:
                rule_name = 'forward'

            forward_rules.append(("redirect", forward_addresses[-1]))
            forward_rules.append(("stop"))

        if forward_uce:
            mgmt_script.addfilter(rule_name, ['true'], forward_rules)

        else:
            # NOTE: Messages with no X-Spam-Status header need to be matched
            # too, and this does exactly that.
            mgmt_script.addfilter(rule_name,
                                  [("not",
                                    ("X-Spam-Status", ":matches", "Yes,*"))],
                                  forward_rules)

    if sdf_filter:
        mgmt_script.addfilter('spam_delivery_folder',
                              [("X-Spam-Status", ":matches", "Yes,*")],
                              [("fileinto", "INBOX/Spam"), ("stop")])

    if dtf_active:
        mgmt_script.addfilter('delivery_to_folder', ['true'],
                              [("fileinto", dtf_folder)])

    mgmt_script = mgmt_script.__str__()

    log.debug(_("MANAGEMENT script for user %s contents: %r") %
              (address, mgmt_script),
              level=9)

    result = sieveclient.putscript("MANAGEMENT", mgmt_script)

    if not result:
        log.error(
            _("Uploading script MANAGEMENT failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MANAGEMENT for user %s succeeded") %
                  (address),
                  level=8)

    user_script = """#
# User
#

require ["include"];
"""

    for script in scripts:
        if not script in ["MASTER", "MANAGEMENT", "USER"]:
            log.debug(_("Including script %s in USER (for user %s)") %
                      (script, address),
                      level=8)
            user_script = """%s

include :personal "%s";
""" % (user_script, script)

    result = sieveclient.putscript("USER", user_script)

    if not result:
        log.error(_("Uploading script USER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script USER for user %s succeeded") % (address),
                  level=8)

    result = sieveclient.putscript(
        "MASTER", """#
# MASTER
#
# This file is authoritative for your system and MUST BE KEPT ACTIVE.
#
# Altering it is likely to render your account dysfunctional and may
# be violating your organizational or corporate policies.
#
# For more information on the mechanism and the conventions behind
# this script, see http://wiki.kolab.org/KEP:14
#

require ["include"];

# OPTIONAL: Includes for all or a group of users
# include :global "all-users";
# include :global "this-group-of-users";

# The script maintained by the general management system
include :personal "MANAGEMENT";

# The script(s) maintained by one or more editors available to the user
include :personal "USER";
""")

    if not result:
        log.error(_("Uploading script MASTER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MASTER for user %s succeeded") %
                  (address),
                  level=8)

    sieveclient.setactive("MASTER")
Ejemplo n.º 20
0
def execute(*args, **kw):
    try:
        email_address = conf.cli_args.pop(0)
    except IndexError, errmsg:
        email_address = utils.ask_question("Email address to remove")

    # Get the domain from the email address
    if len(email_address.split('@')) > 1:
        domain = email_address.split('@')[1]
    else:
        log.error(_("Invalid or unqualified email address."))
        sys.exit(1)

    auth = Auth()
    auth.connect(domain=domain)
    recipients = auth.find_recipient(email_address)

    if len(recipients) == 0:
        log.error(_("No recipient found for email address %r") % (email_address))
        sys.exit(1)

    log.debug(_("Found the following recipient(s): %r") % (recipients), level=8)

    mail_attributes = conf.get_list(domain, 'mail_attributes')
    if mail_attributes == None or len(mail_attributes) < 1:
        mail_attributes = conf.get_list(conf.get('kolab', 'auth_mechanism'), 'mail_attributes')

    log.debug(_("Using the following mail attributes: %r") % (mail_attributes), level=8)

    if isinstance(recipients, basestring):
        recipient = recipients
Ejemplo n.º 21
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port,
                                              conf.debuglevel > 8)

    sieveclient.connect(None, None, True)

    result = sieveclient._plain_authentication(admin_login, admin_password,
                                               address)

    if not result:
        print "LOGIN FAILED??"

    sieveclient.authenticated = True

    result = sieveclient.listscripts()

    if result == None:
        print "No scripts"
        sys.exit(0)

    (active, scripts) = result

    print "%s (active)" % (active)
    for script in scripts:
        print script
Ejemplo n.º 22
0
    def test_002_add_aliases(self):
        auth = Auth()
        auth.connect()

        recipient = auth.find_recipient('*****@*****.**')
        wap_client.user_edit(recipient, {'alias': ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**']})
Ejemplo n.º 23
0
class PolicyRequest(object):
    email_address_keys = [ 'sender', 'recipient' ]
    recipients = []

    auth = None

    sasl_domain = None
    sasl_user = None
    sender_domain = None
    sender_user = None

    sasl_user_uses_alias = False
    sasl_user_is_delegate = False

    def __init__(self, policy_request={}):
        """
            Creates a new policy request object. Pass it a policy_request
            dictionary as described in the Postfix documentation on:

                http://www.postfix.org/SMTPD_POLICY_README.html
        """
        for key in policy_request.keys():

            # Normalize email addresses (they may contain recipient delimiters)
            if key in self.email_address_keys:
                policy_request[key] = normalize_address(policy_request[key])

            if not key == 'recipient':
                if policy_request[key] == '':
                    setattr(self, key, None)
                else:
                    setattr(self, key, policy_request[key])

            else:
                if not policy_request['recipient'].strip() == '':
                    self.recipients = list(set(self.recipients + [policy_request['recipient']]))

    def add_request(self, policy_request={}):
        """
            Add subsequent policy requests to the existing policy request.

            All data in the request should be the same as the initial policy
            request, but for the recipient - with destination limits set over
            1, Postfix may attempt to deliver messages to more then one
            recipient during a single delivery attempt, and during submission,
            the policy will receive one policy request per recipient.
        """

        # Check instance. Not sure what to do if the instance is not the same.
        if hasattr(self, 'instance'):
            if not policy_request['instance'] == self.instance:
                # TODO: We need to empty our pockets
                pass

        log.debug(
                _("Adding policy request to instance %s") % (self.instance),
                level=8
            )

        # Normalize email addresses (they may contain recipient delimiters)
        if policy_request.has_key('recipient'):
            policy_request['recipient'] = normalize_address(
                    policy_request['recipient']
                )

            if not policy_request['recipient'].strip() == '':
                self.recipients = list(set(self.recipients + [policy_request['recipient']]))

    def parse_ldap_dn(self, dn):
        """
            See if parameter 'dn' is a basestring LDAP dn, and if so, return
            the results we can obtain from said DN. Return a list of relevant
            attribute values.

            If not a DN, return None.
        """
        values = []

        try:
            import ldap.dn

            ldap_dn = ldap.dn.explode_dn(dn)

        except ldap.DECODING_ERROR:
            # This is not a DN.
            return None

        if len(ldap_dn) > 0:
            search_attrs = conf.get_list(
                    'kolab_smtp_access_policy',
                    'address_search_attrs'
                )

            rule_subject = self.auth.get_user_attributes(
                    self.sasl_domain,
                    { 'dn': dn },
                    search_attrs + [ 'objectclass' ]
                )

            for search_attr in search_attrs:
                if rule_subject.has_key(search_attr):
                    if isinstance(rule_subject[search_attr], basestring):
                        values.append(rule_subject[search_attr])
                    else:
                        values.extend(rule_subject[search_attr])

            return values

        else:
            # ldap.dn.explode_dn didn't error out, but it also didn't split
            # the DN properly.
            return None

    def parse_ldap_uri(self, uri):
        values = []

        parsed_uri = utils.parse_ldap_uri(uri)

        if parsed_uri == None:
            return None

        (_protocol, _server, _port, _base_dn, _attrs, _scope, _filter) = \
                parsed_uri

        if len(_attrs) == 0:
            search_attrs = conf.get_list(
                    'kolab_smtp_access_policy',
                    'address_search_attrs'
                )
        else:
            search_attrs = [ _attrs ]

        users = []

        self.auth._auth._bind()
        _users = self.auth._auth._search(
                _base_dn,
                scope=LDAP_SCOPE[_scope],
                filterstr=_filter,
                attrlist=search_attrs + [ 'objectclass' ],
                override_search="_regular_search"
            )

        for _user in _users:
            for search_attr in search_attrs:
                values.extend(_user[1][search_attr])

        return values

    def parse_policy(self, _subject, _object, policy):
        """
            Parse policy to apply on _subject, for object _object.

            The policy is a list of rules.

            The _subject is a sender for kolabAllowSMTPRecipient checks, and
            a recipient for kolabAllowSMTPSender checks.

            The _object is a recipient for kolabAllowSMTPRecipient checks, and
            a sender for kolabAllowSMTPSender checks.
        """

        special_rule_values = {
            '$mydomains': expand_mydomains
        }

        rules = { 'allow': [], 'deny': [] }

        if isinstance(policy, basestring):
            policy = [policy]

        for rule in policy:
            # Find rules that are actually special values, simply by
            # mapping the rule onto a key in "special_rule_values", a
            # dictionary with the corresponding value set to a function to
            # execute.
            if rule in special_rule_values.keys():
                special_rules = special_rule_values[rule]()
                if rule.startswith("-"):
                    rules['deny'].extend(special_rules)
                else:
                    rules['allow'].extend(special_rules)

                continue

            # Lower-case the rule
            rule = rule.lower()

            # Also note the '-' cannot be passed on to the functions that
            # follow, so store the rule separately from the prefix that is
            # prepended to deny rules.
            if rule.startswith("-"):
                _prefix = '-'
                _rule = rule[1:]
            else:
                _prefix = ''
                _rule = rule

            # See if the value is an LDAP DN
            ldap_dn = self.parse_ldap_dn(_rule)

            if not ldap_dn == None and len(ldap_dn) > 0:
                if _prefix == '-':
                    rules['deny'].extend(ldap_dn)
                else:
                    rules['allow'].extend(ldap_dn)
            else:
                ldap_uri = self.parse_ldap_uri(_rule)

                if not ldap_uri == None and len(ldap_uri) > 0:
                    if _prefix == '-':
                        rules['deny'].extend(ldap_uri)
                    else:
                        rules['allow'].extend(ldap_uri)

                else:
                    if rule.startswith("-"):
                        rules['deny'].append(rule[1:])
                    else:
                        rules['allow'].append(rule)

        allowed = False
        for rule in rules['allow']:
            deny_override = False

            if _object.endswith(rule):
                for deny_rule in rules['deny']:
                    if deny_rule.endswith(rule):
                        deny_override = True

                if not deny_override:
                    allowed = True

        denied = False

        for rule in rules['deny']:
            allow_override = False
            if _object.endswith(rule):
                if not allowed:
                    denied = True
                    continue
                else:
                    for allow_rule in rules['allow']:
                        if allow_rule.endswith(rule):
                            allow_override = True

                    if not allow_override:
                        denied = True

        if not denied:
            allowed = True

        return allowed

    def verify_alias(self):
        """
            Verify whether the user authenticated for this policy request is
            using an alias of its primary authentication ID / attribute.

            [email protected] (mail) for example could be sending with
            envelope sender [email protected] (mailAlternateAddress, alias).
        """
        search_attrs = conf.get_list(self.sasl_domain, 'mail_attributes')

        if search_attrs == None or \
                (isinstance(search_attrs, list) and len(search_attrs) == 0):

            search_attrs = conf.get_list(
                    conf.get('kolab', 'auth_mechanism'),
                    'mail_attributes'
                )

        # Catch a user using one of its own alias addresses.
        for search_attr in search_attrs:
            if self.sasl_user.has_key(search_attr):
                if isinstance(self.sasl_user[search_attr], list):
                    if self.sender in self.sasl_user[search_attr]:
                        return True
                elif self.sasl_user[search_attr] == self.sender:
                    return True

        return False

    def verify_authenticity(self):
        """
            Verify that the SASL username or lack thereof corresponds with
            allowing or disallowing authenticated users.

            If an SASL username is supplied, use it to obtain the authentication
            database user object including all attributes we may find ourselves
            interested in.
        """

        if self.sasl_username == None:
            if not conf.allow_unauthenticated:
                reject(_("Unauthorized access not allowed"))
            else:
                # If unauthenticated is allowed, I have nothing to do here.
                return True

        sasl_username = self.sasl_username

        # If we have an sasl_username, find the user object in the
        # authentication database, along with the attributes we are
        # interested in.
        if self.sasl_domain == None:
            if len(self.sasl_username.split('@')) > 1:
                self.sasl_domain = self.sasl_username.split('@')[1]
            else:
                self.sasl_domain = conf.get('kolab', 'primary_domain')
                sasl_username = "******" % (self.sasl_username, self.sasl_domain)

        if self.auth == None:
            self.auth = Auth(self.sasl_domain)
        elif not self.auth.domain == self.sasl_domain:
            self.auth = Auth(self.sasl_domain)

        sasl_users = self.auth.find_recipient(
                sasl_username,
                domain=self.sasl_domain
            )

        if isinstance(sasl_users, list):
            if len(sasl_users) == 0:
                log.error(_("Could not find recipient"))
                return False
            else:
                self.sasl_user = { 'dn': sasl_users[0] }
        elif isinstance(sasl_users, basestring):
            self.sasl_user = { 'dn': sasl_users }

        if not self.sasl_user['dn']:
            # Got a final answer here, do the caching thing.
            cache_update(
                    function='verify_sender',
                    sender=self.sender,
                    recipients=self.recipients,
                    result=(int)(False),
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender
                )

            reject(
                    _("Could not find envelope sender user %s") % (
                            self.sasl_username
                        )
                )

        attrs = conf.get_list(self.sasl_domain, 'auth_attributes')

        if attrs == None or (isinstance(attrs, list) and len(attrs) == 0):
            attrs = conf.get_list(
                    conf.get('kolab', 'auth_mechanism'),
                    'auth_attributes'
                )

        mail_attrs = conf.get_list(self.sasl_domain, 'mail_attributes')
        if mail_attrs == None or \
                (isinstance(mail_attrs, list) and len(mail_attrs) == 0):

            mail_attrs = conf.get_list(
                    conf.get('kolab', 'auth_mechanism'),
                    'mail_attributes'
                )

        if not mail_attrs == None:
            attrs.extend(mail_attrs)

        attrs.extend(
                [
                        'kolabAllowSMTPRecipient',
                        'kolabAllowSMTPSender'
                    ]
            )

        attrs = list(set(attrs))

        user_attrs = self.auth.get_user_attributes(
                self.sasl_domain,
                self.sasl_user,
                attrs
            )

        user_attrs['dn'] = self.sasl_user['dn']
        self.sasl_user = utils.normalize(user_attrs)
        log.debug(
                _("Obtained authenticated user details for %r: %r") % (
                        self.sasl_user['dn'],
                        self.sasl_user.keys()
                    ),
                level=8
            )

    def verify_delegate(self):
        """
            Verify whether the authenticated user is a delegate of the envelope
            sender.
        """

        if self.sender_domain == None:
            if len(self.sender.split('@')) > 1:
                self.sender_domain = self.sender.split('@')[1]
            else:
                self.sender_domain = conf.get('kolab', 'primary_domain')

        if self.sender == self.sasl_username:
            return True

        search_attrs = conf.get_list(self.sender_domain, 'mail_attributes')
        if search_attrs == None:
            search_attrs = conf.get_list(
                    conf.get('kolab', 'auth_mechanism'),
                    'mail_attributes'
                )

        sender_users = self.auth.find_recipient(
                self.sender,
                domain=self.sender_domain
            )

        if isinstance(sender_users, list):
            if len(sender_users) > 1:
                # More then one sender user with this recipient address.
                # TODO: check each of the sender users found.
                self.sender_user = { 'dn': sender_users[0] }
            elif len(sender_users) == 1:
                self.sender_user = { 'dn': sender_users }
            else:
                self.sender_user = { 'dn': False }

        elif isinstance(sender_users, basestring):
            self.sender_user = { 'dn': sender_users }

        if not self.sender_user['dn']:
            cache_update(
                    function='verify_sender',
                    sender=self.sender,
                    recipients=self.recipients,
                    result=(int)(False),
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender
                )

            reject(_("Could not find envelope sender user %s") % (self.sender))

        attrs = search_attrs
        attrs.extend(
                [
                        'kolabAllowSMTPRecipient',
                        'kolabAllowSMTPSender',
                        'kolabDelegate'
                    ]
            )

        user_attrs = self.auth.get_user_attributes(
                self.sender_domain,
                self.sender_user,
                attrs
            )

        user_attrs['dn'] = self.sender_user['dn']
        self.sender_user = utils.normalize(user_attrs)

        if not self.sender_user.has_key('kolabdelegate'):
            reject(
                    _("%s is unauthorized to send on behalf of %s") % (
                            self.sasl_user['dn'],
                            self.sender_user['dn']
                        )
                )

        elif self.sender_user['kolabdelegate'] == None:
            # No delegates for this sender could be found. The user is
            # definitely NOT a delegate of the sender.
            log.warning(
                _("User %s attempted to use envelope sender address %s " + \
                    "without authorization") % (
                            policy_request["sasl_username"],
                            policy_request["sender"]
                        )
                )

            # Got a final answer here, do the caching thing.
            if not cache == False:
                record_id = cache_update(
                        function='verify_sender',
                        sender=self.sender,
                        recipients=self.recipients,
                        result=(int)(False),
                        sasl_username=self.sasl_username,
                        sasl_sender=self.sasl_sender
                    )

            sender_is_delegate = False

        else:
            # See if we can match the value of the envelope sender delegates to
            # the actual sender sasl_username
            if self.sasl_user == None:
                sasl_users = self.auth.find_recipient(
                        self.sasl_username,
                        domain=self.sasl_domain
                    )

                if isinstance(sasl_users, list):
                    if len(sasl_users) == 0:
                        log.error(_("Could not find recipient"))
                        return False
                    else:
                        self.sasl_user = { 'dn': sasl_users[0] }
                elif isinstance(sasl_users, basestring):
                    self.sasl_user = { 'dn': sasl_users }

            # Possible values for the kolabDelegate attribute are:
            # a 'uid', a 'dn'.
            if not self.sasl_user.has_key('uid'):
                self.sasl_user['uid'] = self.auth.get_user_attribute(
                        self.sasl_domain,
                        self.sasl_user,
                        'uid'
                    )

            sender_delegates = self.sender_user['kolabdelegate']

            if not type(sender_delegates) == list:
                sender_delegates = [ sender_delegates ]

            for sender_delegate in sender_delegates:
                if self.sasl_user['dn'] == sender_delegate:
                    log.debug(
                            _("Found user %s to be a delegate user of %s") % (
                                    policy_request["sasl_username"],
                                    policy_request["sender"]
                                ),
                            level=8
                        )

                    sender_is_delegate = True

                elif self.sasl_user['uid'] == sender_delegate:
                    log.debug(
                            _("Found user %s to be a delegate user of %s") % (
                                    policy_request["sasl_username"],
                                    policy_request["sender"]
                                ),
                            level=8
                        )

                    sender_is_delegate = True

            # If nothing matches sender_is_delegate is still None.
            if not sender_is_delegate == True:
                sender_is_delegate = False

        return sender_is_delegate

    def verify_recipient(self, recipient):
        """
            Verify whether the sender is allowed send to this recipient, using
            the recipient's kolabAllowSMTPSender.
        """

        self.recipient = recipient

        if not self.sasl_username == '' and not self.sasl_username == None:
            log.debug(_("Verifying authenticated sender '%(sender)s' with " + \
                    "sasl_username '%(sasl_username)s' for recipient " + \
                    "'%(recipient)s'") % (self.__dict__)
                )
        else:
            log.debug(_("Verifying unauthenticated sender '%(sender)s' " + \
                    "for recipient '%(recipient)s'") % (self.__dict__)
                )

        recipient_verified = False

        if not cache == False:
            records = cache_select(
                    function='verify_recipient',
                    sender=self.sender,
                    recipient=recipient,
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender,
                )

            if not records == None and len(records) == 1:
                log.info(
                        _("Reproducing verify_recipient(%s, %s) from " + \
                            "cache, saving you queries, time and thus " + \
                            "money.") % (self.sender, recipient)
                    )

                return record[0].value

        # TODO: Under some conditions, the recipient may not be fully qualified.
        # We'll cross that bridge when we get there, though.
        if len(recipient.split('@')) > 1:
            sasl_domain = recipient.split('@')[1]
        else:
            sasl_domain = conf.get('kolab', 'primary_domain')

        if self.auth == None:
            self.auth = Auth(sasl_domain)
        elif not self.auth.domain == sasl_domain:
            self.auth = Auth(sasl_domain)

        if verify_domain(sasl_domain):
            if self.auth.secondary_domains.has_key(sasl_domain):
                log.debug(
                        _("Using authentication domain %s instead of %s") % (
                                self.auth.secondary_domains[sasl_domain],
                                sasl_domain
                            ),
                        level=8
                    )

                sasl_domain = self.auth.secondary_domains[sasl_domain]
            else:
                log.debug(
                        _("Domain %s is a primary domain") % (
                                sasl_domain
                        ),
                        level=8
                    )

        else:
            log.warning(
                    _("Checking the recipient for domain %s that is not " + \
                    "ours. This is probably a configuration error.") % (
                            sasl_domain
                        )
                )

            return True

        recipients = self.auth.find_recipient(
                normalize_address(recipient),
                domain=sasl_domain,
            )

        if isinstance(recipients, list):
            if len(recipients) > 1:
                log.info(
                        _("This recipient address is related to multiple " + \
                            "object entries and the SMTP Access Policy can " + \
                            "therefore not restrict message flow")
                    )
                return True
            elif len(recipients) == 1:
                recipient = { 'dn': recipients[0] }
            else:
                log.debug(
                        _("Recipient address %r not found. Allowing since " + \
                            "the MTA was configured to accept the recipient.") % (
                                normalize_address(recipient)
                            ),
                        level=3
                    )

                return True

        elif isinstance(recipients, basestring):
            recipient = {
                    'dn': recipients
                }

        # We have gotten an invalid recipient. We need to catch this case,
        # because testing can input invalid recipients, and so can faulty
        # applications, or misconfigured servers.
        if not recipient['dn']:
            if not conf.allow_unauthenticated:
                cache_update(
                        function='verify_recipient',
                        sender=self.sender,
                        recipient=recipient,
                        result=(int)(False),
                        sasl_username=self.sasl_username,
                        sasl_sender=self.sasl_sender
                    )

                reject(_("Invalid recipient"))
            else:
                cache_update(
                        function='verify_recipient',
                        sender=self.sender,
                        recipient=recipient,
                        result=(int)(True),
                        sasl_username=self.sasl_username,
                        sasl_sender=self.sasl_sender
                    )

                log.debug(_("Could not find this user, accepting"), level=8)
                return True

        if not recipient['dn'] == False:
            recipient_policy = self.auth.get_entry_attribute(
                    sasl_domain,
                    recipient,
                    'kolabAllowSMTPSender'
                )

        # If no such attribute has been specified, allow
        if recipient_policy == None:
            recipient_verified = True

        # Otherwise, parse the policy obtained with the subject of the policy
        # being the recipient, and the object to apply the policy to being the
        # sender.
        else:
            recipient_verified = self.parse_policy(
                    recipient,
                    self.sender,
                    recipient_policy
                )

            cache_update(
                    function='verify_recipient',
                    sender=self.sender,
                    recipient=recipient,
                    result=(int)(recipient_verified),
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender
                )

        return recipient_verified

    def verify_recipients(self):
        """
            Verify whether the sender is allowed send to the recipients in this
            policy request, using each recipient's kolabAllowSMTPSender.

            Note there may be multiple recipients in this policy request, and
            therefor self.recipients is a list - walk through that list.
        """

        recipients_verified = True

        if not cache == False:
            records = cache_select(
                    function='verify_recipient',
                    sender=self.sender,
                    recipients=self.recipients,
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender,
                )

            if not records == None and len(records) == len(self.recipients):
                for record in records:
                    recipient_found = False
                    for recipient in self.recipients:
                        if recipient == record['recipient']:
                            recipient_found = True

                    if not recipient_found:
                        reject(_("Sender %s is not allowed to send to " + \
                                "recipient %s") % (self.sender,recipient))

        for recipient in self.recipients:
            recipient_verified = self.verify_recipient(recipient)
            if not recipient_verified:
                recipients_verified = False

        return recipients_verified

    def verify_sender(self):
        """
            Verify the sender's access policy.

            1) Verify whether the sasl_username is allowed to send using the
            envelope sender address, with the kolabDelegate attribute
            associated with the LDAP object that has the envelope sender
            address.

            2) Verify whether the sender is allowed to send to recipient(s)
            listed on the sender's object.

            A third potential action could be to check the recipient object to
            see if the sender is allowed to send to the recipient by the
            recipient's kolabAllowSMTPSender, but this is done in
            verify_recipients().
        """

        sender_verified = False

        if not cache == False:
            records = cache_select(
                    sender=self.sender,
                    recipients=self.recipients,
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender,
                    function='verify_sender'
                )

            if not records == None and len(records) == len(self.recipients):
                log.info(_("Reproducing verify_sender(%r) from cache, " + \
                        "saving you queries, time and thus money.") % (
                                self.__dict__
                            )
                    )

                for record in records:
                    recipient_found = False
                    for recipient in self.recipients:
                        if recipient == record.recipient:
                            recipient_found = True

                    if recipient_found and not record.value:
                        reject(_("Sender %s is not allowed to send to " + \
                                "recipient %s") % (self.sender,recipient))

                return True

        self.verify_authenticity()
        self.sasl_user_uses_alias = self.verify_alias()

        if not self.sasl_user_uses_alias:
            self.sasl_user_is_delegate = self.verify_delegate()

        # If the authenticated user is using delegate functionality, apply the
        # recipient policy attribute for the envelope sender.
        if self.sasl_user_is_delegate == False and \
            self.sasl_user_uses_alias == False:

            reject(_("Sender uses unauthorized envelope sender address"))

        elif self.sasl_user_is_delegate:
            # Apply the recipient policy for the sender using the envelope
            # sender user object.
            recipient_policy_domain = self.sender_domain
            recipient_policy_sender = self.sender
            recipient_policy_user = self.sender_user

        elif not self.sasl_user == None:
            # Apply the recipient policy from the authenticated user.
            recipient_policy_domain = self.sasl_domain
            recipient_policy_sender = self.sasl_username
            recipient_policy_user = self.sasl_user

        else:
            if not conf.allow_unauthenticated:
                reject(_("Could not verify sender"))
            else:
                recipient_policy_domain = self.sender_domain
                recipient_policy_sender = self.sender
                recipient_policy_user = self.sender_user

        log.debug(
                _("Verifying whether sender is allowed to send to " + \
                    "recipient using sender policy"),
                level=8
            )

        if recipient_policy_user.has_key('kolaballowsmtprecipient'):
            recipient_policy = recipient_policy_user['kolaballowsmtprecipient']
        else:
            recipient_policy = self.auth.get_user_attribute(
                    recipient_policy_domain,
                    recipient_policy_user,
                    'kolabAllowSMTPRecipient'
                )

        log.debug(_("Result is %r") % (recipient_policy), level=8)

        # If no such attribute has been specified, allow
        if recipient_policy == None:
            log.debug(
                    _("No recipient policy restrictions exist for this sender"),
                    level=8
                )

            sender_verified = True

        # Otherwise,parse the policy obtained.
        else:
            log.debug(
                    _("Found a recipient policy to apply for this sender."),
                    level=8
                )

            recipient_allowed = None

            for recipient in self.recipients:
                recipient_allowed = self.parse_policy(
                        recipient_policy_sender,
                        recipient,
                        recipient_policy
                    )

                if not recipient_allowed:
                    reject(
                            _("Sender %s not allowed to send to recipient " + \
                                "%s") % (recipient_policy_user['dn'],recipient)
                        )

            sender_verified = True

        if not cache == False:
            record_id = cache_update(
                    function='verify_sender',
                    sender=self.sender,
                    recipients=self.recipients,
                    result=(int)(sender_verified),
                    sasl_username=self.sasl_username,
                    sasl_sender=self.sasl_sender
                )

        return sender_verified
Ejemplo n.º 24
0
def execute(*args, **kw):

    try:
        primary_rcpt_address = conf.cli_args.pop(0)
        try:
            secondary_rcpt_address = conf.cli_args.pop(0)
        except:
            print >> sys.stderr, _("Specify the (new) alias address")
            sys.exit(1)
    except:
        print >> sys.stderr, _("Specify the existing recipient address")
        sys.exit(1)

    if len(primary_rcpt_address.split('@')) > 1:
        primary_rcpt_domain = primary_rcpt_address.split('@')[-1]
    else:
        primary_rcpt_domain = conf.get('kolab', 'primary_domain')

    auth = Auth(domain=primary_rcpt_domain)

    domains = auth.list_domains()

    #print domains

    if len(secondary_rcpt_address.split('@')) > 1:
        secondary_rcpt_domain = secondary_rcpt_address.split('@')[-1]
    else:
        secondary_rcpt_domain = conf.get('kolab', 'primary_domain')

    # Check if either is in fact a domain
    if not primary_rcpt_domain.lower() in domains.keys():
        print >> sys.stderr, _("Domain %r is not a local domain") % (primary_rcpt_domain)
        sys.exit(1)

    if not secondary_rcpt_domain.lower() in domains.keys():
        print >> sys.stderr, _("Domain %r is not a local domain") % (secondary_rcpt_domain)
        sys.exit(1)

    if not primary_rcpt_domain == secondary_rcpt_domain:
        if not domains[primary_rcpt_domain] == domains[secondary_rcpt_domain]:
            print >> sys.stderr, _("Primary and secondary domain do not have the same parent domain")
            sys.exit(1)

    primary_recipient_dn = auth.find_recipient(primary_rcpt_address)

    if primary_recipient_dn == [] or len(primary_recipient_dn) == 0:
        print >> sys.stderr, _("No such recipient %r") % (primary_rcpt_address)
        sys.exit(1)

    secondary_recipient_dn = auth.find_recipient(secondary_rcpt_address)

    if not secondary_recipient_dn == [] and not len(secondary_recipient_dn) == 0:
        print >> sys.stderr, _("Recipient for alias %r already exists") % (secondary_rcpt_address)
        sys.exit(1)

    rcpt_attrs = conf.get_list('ldap', 'mail_attributes')

    primary_rcpt_attr = rcpt_attrs[0]

    if len(rcpt_attrs) >= 2:
        secondary_rcpt_attr = rcpt_attrs[1]
    else:
        print >> sys.stderr, _("Environment is not configured for " + \
            "users to hold secondary mail attributes")

        sys.exit(1)

    primary_recipient = auth.get_entry_attributes(primary_rcpt_domain, primary_recipient_dn, rcpt_attrs)

    if not primary_recipient.has_key(primary_rcpt_attr):
        print >> sys.stderr, _("Recipient %r is not the primary recipient for address %r") % (primary_recipient, primary_rcpt_address)
        sys.exit(1)

    if not primary_recipient.has_key(secondary_rcpt_attr):
        auth.set_entry_attributes(primary_rcpt_domain, primary_recipient_dn, {secondary_rcpt_attr: [ secondary_rcpt_address ] })
    else:
        if isinstance(primary_recipient[secondary_rcpt_attr], basestring):
            new_secondary_rcpt_attrs = [
                    primary_recipient[secondary_rcpt_attr],
                    secondary_rcpt_address
                ]

        else:
            new_secondary_rcpt_attrs = \
                    primary_recipient[secondary_rcpt_attr] + \
                    [ secondary_rcpt_address ]

        auth.set_entry_attributes(
                primary_rcpt_domain,
                primary_recipient_dn,
                {
                        secondary_rcpt_attr: new_secondary_rcpt_attrs
                    }
            )
Ejemplo n.º 25
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port, conf.debuglevel > 8)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    result = sieveclient.listscripts()

    if result == None:
        active = None
        scripts = []
    else:
        active, scripts = result

    log.debug(_("Found the following scripts for user %s: %s") % (address, ','.join(scripts)), level=8)
    log.debug(_("And the following script is active for user %s: %s") % (address, active), level=8)

    mgmt_required_extensions = []

    mgmt_script = """#
# MANAGEMENT
#
"""

    user = auth.get_entry_attributes(domain, user, ['*'])

    #
    # Vacation settings (a.k.a. Out of Office)
    #
    vacation_active = None
    vacation_text = None
    vacation_uce = None
    vacation_noreact_domains = None
    vacation_react_domains = None

    vacation_active_attr = conf.get('sieve', 'vacation_active_attr')
    vacation_text_attr = conf.get('sieve', 'vacation_text_attr')
    vacation_uce_attr = conf.get('sieve', 'vacation_uce_attr')
    vacation_noreact_domains_attr = conf.get('sieve', 'vacation_noreact_domains_attr')
    vacation_react_domains_attr = conf.get('sieve', 'vacation_react_domains_attr')

    if not vacation_text_attr == None:

        if user.has_key(vacation_active_attr):
            vacation_active = utils.true_or_false(user[vacation_active_attr])
        else:
            vacation_active = False

        if user.has_key(vacation_text_attr):
            vacation_text = user[vacation_text_attr]
        else:
            vacation_active = False

        if user.has_key(vacation_uce_attr):
            vacation_uce = utils.true_or_false(user[vacation_uce_attr])
        else:
            vacation_uce = False

        if user.has_key(vacation_react_domains_attr):
            if isinstance(user[vacation_react_domains_attr], list):
                vacation_react_domains = user[vacation_react_domains_attr]
            else:
                vacation_react_domains = [ user[vacation_react_domains_attr] ]
        else:
            if user.has_key(vacation_noreact_domains_attr):
                if isinstance(user[vacation_noreact_domains_attr], list):
                    vacation_noreact_domains = user[vacation_noreact_domains_attr]
                else:
                    vacation_noreact_domains = [ user[vacation_noreact_domains_attr] ]
            else:
                vacation_noreact_domains = []

    #
    # Delivery to Folder
    #
    dtf_active_attr = conf.get('sieve', 'deliver_to_folder_active')
    if not dtf_active_attr == None:
        if user.has_key(dtf_active_attr):
            dtf_active = utils.true_or_false(user[dtf_active_attr])
        else:
            dtf_active = False
    else:
        # TODO: Not necessarily de-activated, the *Active attributes are
        # not supposed to charge this - check the deliver_to_folder_attr
        # attribute value for a value.
        dtf_active = False

    if dtf_active:
        dtf_folder_name_attr = conf.get('sieve', 'deliver_to_folder_attr')
        if not dtf_folder_name_attr == None:
            if user.has_key(dtf_folder_name_attr):
                dtf_folder = user[dtf_folder_name_attr]
            else:
                log.warning(_("Delivery to folder active, but no folder name attribute available for user %r") % (user))
                dtf_active = False
        else:
            log.error(_("Delivery to folder active, but no folder name attribute configured"))
            dtf_active = False

    #
    # Folder name to delivery spam to.
    #
    # Global or local.
    #
    sdf_filter = True
    sdf = conf.get('sieve', 'spam_global_folder')

    if sdf == None:
        sdf = conf.get('sieve', 'spam_personal_folder')
        if sdf == None:
            sdf_filter = False

    #
    # Mail forwarding
    #
    forward_active = None
    forward_addresses = []
    forward_keepcopy = None
    forward_uce = None

    forward_active_attr = conf.get('sieve', 'forward_address_active')
    if not forward_active_attr == None:
        if user.has_key(forward_active_attr):
            forward_active = utils.true_or_false(user[forward_active_attr])
        else:
            forward_active = False

    if not forward_active == False:
        forward_address_attr = conf.get('sieve', 'forward_address_attr')
        if user.has_key(forward_address_attr):
            if isinstance(user[forward_address_attr], basestring):
                forward_addresses = [ user[forward_address_attr] ]
            elif isinstance(user[forward_address_attr], str):
                forward_addresses = [ user[forward_address_attr] ]
            else:
                forward_addresses = user[forward_address_attr]

        if len(forward_addresses) == 0:
            forward_active = False

        forward_keepcopy_attr = conf.get('sieve', 'forward_keepcopy_active')
        if not forward_keepcopy_attr == None:
            if user.has_key(forward_keepcopy_attr):
                forward_keepcopy = utils.true_or_false(user[forward_keepcopy_attr])
            else:
                forward_keepcopy = False

        forward_uce_attr = conf.get('sieve', 'forward_uce_active')
        if not forward_uce_attr == None:
            if user.has_key(forward_uce_attr):
                forward_uce = utils.true_or_false(user[forward_uce_attr])
            else:
                forward_uce = False

    if vacation_active:
        mgmt_required_extensions.append('vacation')
        mgmt_required_extensions.append('envelope')

    if dtf_active:
        mgmt_required_extensions.append('fileinto')

    if forward_active and (len(forward_addresses) > 1 or forward_keepcopy):
        mgmt_required_extensions.append('copy')

    if sdf_filter:
        mgmt_required_extensions.append('fileinto')

    import sievelib.factory

    mgmt_script = sievelib.factory.FiltersSet("MANAGEMENT")

    for required_extension in mgmt_required_extensions:
        mgmt_script.require(required_extension)

    mgmt_script.require('fileinto')

    if vacation_active:
        if not vacation_react_domains == None and len(vacation_react_domains) > 0:
            mgmt_script.addfilter(
                    'vacation',
                    [('envelope', ':domain', ":is", "from", vacation_react_domains)],
                    [
                            (
                                    "vacation",
                                    ":days", 1,
                                    ":subject",
                                    "Out of Office",
                                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                                    # ":mime", to indicate the reason is in fact MIME
                                    vacation_text
                                )
                        ]
                )

        elif not vacation_noreact_domains == None and len(vacation_noreact_domains) > 0:
            mgmt_script.addfilter(
                    'vacation',
                    [('not', ('envelope', ':domain', ":is", "from", vacation_noreact_domains))],
                    [
                            (
                                    "vacation",
                                    ":days", 1,
                                    ":subject",
                                    "Out of Office",
                                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                                    # ":mime", to indicate the reason is in fact MIME
                                    vacation_text
                                )
                        ]
                )

        else:
            mgmt_script.addfilter(
                    'vacation',
                    [('true',)],
                    [
                            (
                                    "vacation",
                                    ":days", 1,
                                    ":subject",
                                    "Out of Office",
                                    # ":handle", see http://tools.ietf.org/html/rfc5230#page-4
                                    # ":mime", to indicate the reason is in fact MIME
                                    vacation_text
                                )
                        ]
                )

    if forward_active:
        forward_rules = []

        # Principle can be demonstrated by:
        #
        # python -c "print ','.join(['a','b','c'][:-1])"
        #
        for forward_copy in forward_addresses[:-1]:
            forward_rules.append(("redirect", ":copy", forward_copy))

        if forward_keepcopy:
            # Principle can be demonstrated by:
            #
            # python -c "print ','.join(['a','b','c'][-1])"
            #
            if forward_uce:
                rule_name = 'forward-uce-keepcopy'
            else:
                rule_name = 'forward-keepcopy'

            forward_rules.append(("redirect", ":copy", forward_addresses[-1]))
        else:
            if forward_uce:
                rule_name = 'forward-uce'
            else:
                rule_name = 'forward'

            forward_rules.append(("redirect", forward_addresses[-1]))
            forward_rules.append(("stop"))

        if forward_uce:
            mgmt_script.addfilter(rule_name, ['true'], forward_rules)

        else:
            # NOTE: Messages with no X-Spam-Status header need to be matched
            # too, and this does exactly that.
            mgmt_script.addfilter(rule_name, [("not", ("X-Spam-Status", ":matches", "Yes,*"))], forward_rules)

    if sdf_filter:
        mgmt_script.addfilter('spam_delivery_folder', [("X-Spam-Status", ":matches", "Yes,*")], [("fileinto", "INBOX/Spam"), ("stop")])

    if dtf_active:
        mgmt_script.addfilter('delivery_to_folder', ['true'], [("fileinto", dtf_folder)])

    mgmt_script = mgmt_script.__str__()

    log.debug(_("MANAGEMENT script for user %s contents: %r") % (address,mgmt_script), level=9)

    result = sieveclient.putscript("MANAGEMENT", mgmt_script)

    if not result:
        log.error(_("Uploading script MANAGEMENT failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MANAGEMENT for user %s succeeded") % (address), level=8)

    user_script = """#
# User
#

require ["include"];
"""

    for script in scripts:
        if not script in [ "MASTER", "MANAGEMENT", "USER" ]:
            log.debug(_("Including script %s in USER (for user %s)") % (script,address) ,level=8)
            user_script = """%s

include :personal "%s";
""" % (user_script, script)

    result = sieveclient.putscript("USER", user_script)

    if not result:
        log.error(_("Uploading script USER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script USER for user %s succeeded") % (address), level=8)

    result = sieveclient.putscript("MASTER", """#
# MASTER
#
# This file is authoritative for your system and MUST BE KEPT ACTIVE.
#
# Altering it is likely to render your account dysfunctional and may
# be violating your organizational or corporate policies.
#
# For more information on the mechanism and the conventions behind
# this script, see http://wiki.kolab.org/KEP:14
#

require ["include"];

# OPTIONAL: Includes for all or a group of users
# include :global "all-users";
# include :global "this-group-of-users";

# The script maintained by the general management system
include :personal "MANAGEMENT";

# The script(s) maintained by one or more editors available to the user
include :personal "USER";
""")

    if not result:
        log.error(_("Uploading script MASTER failed for user %s") % (address))
    else:
        log.debug(_("Uploading script MASTER for user %s succeeded") % (address), level=8)

    sieveclient.setactive("MASTER")
Ejemplo n.º 26
0
        for secondary in secondaries:
            folders.extend(imap.lm('shared/%%@%s' % (secondary)))
            folders.extend(imap.lm('user/%%@%s' % (secondary)))

        auth = Auth(domain=primary)
        auth.connect()

        for folder in folders:
            server = imap.user_mailbox_server(folder)
            r_folder = folder

            if folder.startswith('shared/'):
                recipient = auth.find_folder_resource(folder)
            else:
                r_folder = '/'.join(folder.split('/')[1:])
                recipient = auth.find_recipient(
                    r_folder, search_attrs=[result_attribute])

            if (isinstance(recipient, list)):
                if len(recipient) > 1:
                    log.warning(
                        _("Multiple recipients for '%s'!") % (r_folder))
                    continue
                elif len(recipient) == 0:
                    if conf.delete:
                        if conf.dry_run:
                            if not folder.startswith('shared/'):
                                log.warning(
                                    _("No recipients for '%s' (would have deleted the mailbox if not for --dry-run)!"
                                      ) % (r_folder))
                            else:
                                continue
Ejemplo n.º 27
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve
 
    sieveclient = sievelib.managesieve.Client(hostname, port, True)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    active, scripts = sieveclient.listscripts()

    print "%s (active)" % (active)
    
    _all_scripts = [ active ] + scripts
    _used_scripts = [ active ]
    _included_scripts = []

    _a_script = sieveclient.getscript(active)

    print _a_script

    import sievelib.parser

    _a_parser = sievelib.parser.Parser(debug=True)
    _a_parsed = _a_parser.parse(_a_script)

    #print "%r" % (_a_parsed)

    if not _a_parsed:
        print _a_parser.error

    print "%r" % (_a_parser.result)

    for _a_command in _a_parser.result:
        print _a_command.name, _a_command.arguments
        if len(_a_command.children) > 0:
            for _a_child in _a_command.children:
                print "  ", _a_child.name, _a_child.arguments

        if _a_command.name == "include":
            if _a_command.arguments["script"].strip('"') in scripts:
                print "OK"
                _used_scripts.append(_a_command.arguments["script"].strip('"'))
            else:
                print "Not OK"

    for script in scripts:
        print script
Ejemplo n.º 28
0
def execute(*args, **kw):

    try:
        primary_rcpt_address = conf.cli_args.pop(0)
        try:
            secondary_rcpt_address = conf.cli_args.pop(0)
        except:
            print >> sys.stderr, _("Specify the (new) alias address")
            sys.exit(1)
    except:
        print >> sys.stderr, _("Specify the existing recipient address")
        sys.exit(1)

    if len(primary_rcpt_address.split('@')) > 1:
        primary_rcpt_domain = primary_rcpt_address.split('@')[-1]
    else:
        primary_rcpt_domain = conf.get('kolab', 'primary_domain')

    auth = Auth(domain=primary_rcpt_domain)

    domains = auth.list_domains()

    #print domains

    if len(secondary_rcpt_address.split('@')) > 1:
        secondary_rcpt_domain = secondary_rcpt_address.split('@')[-1]
    else:
        secondary_rcpt_domain = conf.get('kolab', 'primary_domain')

    # Check if either is in fact a domain
    if not primary_rcpt_domain.lower() in domains.keys():
        print >> sys.stderr, _("Domain %r is not a local domain") % (
            primary_rcpt_domain)
        sys.exit(1)

    if not secondary_rcpt_domain.lower() in domains.keys():
        print >> sys.stderr, _("Domain %r is not a local domain") % (
            secondary_rcpt_domain)
        sys.exit(1)

    if not primary_rcpt_domain == secondary_rcpt_domain:
        if not domains[primary_rcpt_domain] == domains[secondary_rcpt_domain]:
            print >> sys.stderr, _(
                "Primary and secondary domain do not have the same parent domain"
            )
            sys.exit(1)

    primary_recipient_dn = auth.find_recipient(primary_rcpt_address)

    if primary_recipient_dn == [] or len(primary_recipient_dn) == 0:
        print >> sys.stderr, _("No such recipient %r") % (primary_rcpt_address)
        sys.exit(1)

    secondary_recipient_dn = auth.find_recipient(secondary_rcpt_address)

    if not secondary_recipient_dn == [] and not len(
            secondary_recipient_dn) == 0:
        print >> sys.stderr, _("Recipient for alias %r already exists") % (
            secondary_rcpt_address)
        sys.exit(1)

    rcpt_attrs = conf.get_list('ldap', 'mail_attributes')

    primary_rcpt_attr = rcpt_attrs[0]

    if len(rcpt_attrs) >= 2:
        secondary_rcpt_attr = rcpt_attrs[1]
    else:
        print >> sys.stderr, _("Environment is not configured for " + \
            "users to hold secondary mail attributes")

        sys.exit(1)

    primary_recipient = auth.get_entry_attributes(primary_rcpt_domain,
                                                  primary_recipient_dn,
                                                  rcpt_attrs)

    if not primary_recipient.has_key(primary_rcpt_attr):
        print >> sys.stderr, _(
            "Recipient %r is not the primary recipient for address %r") % (
                primary_recipient, primary_rcpt_address)
        sys.exit(1)

    if not primary_recipient.has_key(secondary_rcpt_attr):
        auth.set_entry_attributes(
            primary_rcpt_domain, primary_recipient_dn,
            {secondary_rcpt_attr: [secondary_rcpt_address]})
    else:
        if isinstance(primary_recipient[secondary_rcpt_attr], basestring):
            new_secondary_rcpt_attrs = [
                primary_recipient[secondary_rcpt_attr], secondary_rcpt_address
            ]

        else:
            new_secondary_rcpt_attrs = \
                    primary_recipient[secondary_rcpt_attr] + \
                    [ secondary_rcpt_address ]

        auth.set_entry_attributes(
            primary_rcpt_domain, primary_recipient_dn,
            {secondary_rcpt_attr: new_secondary_rcpt_attrs})
Ejemplo n.º 29
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port, True)
    sieveclient.connect(None, None, True)
    sieveclient._plain_authentication(admin_login, admin_password, address)
    sieveclient.authenticated = True

    active, scripts = sieveclient.listscripts()

    print "%s (active)" % (active)

    _all_scripts = [active] + scripts
    _used_scripts = [active]
    _included_scripts = []

    _a_script = sieveclient.getscript(active)

    print _a_script

    import sievelib.parser

    _a_parser = sievelib.parser.Parser(debug=True)
    _a_parsed = _a_parser.parse(_a_script)

    #print "%r" % (_a_parsed)

    if not _a_parsed:
        print _a_parser.error

    print "%r" % (_a_parser.result)

    for _a_command in _a_parser.result:
        print _a_command.name, _a_command.arguments
        if len(_a_command.children) > 0:
            for _a_child in _a_command.children:
                print "  ", _a_child.name, _a_child.arguments

        if _a_command.name == "include":
            if _a_command.arguments["script"].strip('"') in scripts:
                print "OK"
                _used_scripts.append(_a_command.arguments["script"].strip('"'))
            else:
                print "Not OK"

    for script in scripts:
        print script
Ejemplo n.º 30
0
def execute(*args, **kw):
    """
        List mailboxes
    """

    auth = Auth()
    domains = auth.list_domains()

    imap = IMAP()
    imap.connect()

    domain_folders = {}

    subjects = []
    # Placeholder for subjects that would have already been deleted
    subjects_deleted = []

    for domain in domains.keys():
        domain_folders[domain] = imap.lm("user/%%@%s" % (domain))

    for domain in domain_folders.keys():
        auth = Auth(domain=domain)
        auth.connect(domain)

        for folder in domain_folders[domain]:
            user = folder.replace('user/', '')

            try:
                recipient = auth.find_recipient(user)
            except ldap.NO_SUCH_OBJECT, errmsg:
                if not user in subjects_deleted and conf.dryrun:
                    subjects_deleted.append(user)

                if conf.dryrun:
                    log.info(
                        _("Would have deleted folder 'user/%s' (dryrun)") %
                        (user))
                else:
                    log.info(_("Deleting folder 'user/%s'") % (user))
                continue

            if len(recipient) == 0 or recipient == []:
                if not user in subjects_deleted and conf.dryrun:
                    subjects_deleted.append(user)

                if conf.dryrun:
                    log.info(
                        _("Would have deleted folder 'user/%s' (dryrun)") %
                        (user))
                else:
                    log.info(_("Deleting folder 'user/%s'") % (user))
                    try:
                        imap.dm(folder)
                    except:
                        log.error(
                            _("Error deleting folder 'user/%s'") % (user))
            else:
                log.debug(_("Valid recipient found for 'user/%s'") % (user),
                          level=6)

                if not user in subjects:
                    subjects.append(user)
Ejemplo n.º 31
0
def execute(*args, **kw):
    try:
        address = conf.cli_args.pop(0)
    except:
        address = utils.ask_question(_("Email Address"))

    auth = Auth()
    auth.connect()

    user = auth.find_recipient(address)

    # Get the main, default backend
    backend = conf.get('kolab', 'imap_backend')

    if len(address.split('@')) > 1:
        domain = address.split('@')[1]
    else:
        domain = conf.get('kolab', 'primary_domain')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_backend'):
        backend = conf.get(domain, 'imap_backend')

    if conf.has_section(domain) and conf.has_option(domain, 'imap_uri'):
        uri = conf.get(domain, 'imap_uri')
    else:
        uri = conf.get(backend, 'uri')

    hostname = None
    port = None

    result = urlparse(uri)

    if hasattr(result, 'hostname'):
        hostname = result.hostname
    else:
        scheme = uri.split(':')[0]
        (hostname, port) = uri.split('/')[2].split(':')

    port = 4190

    # Get the credentials
    admin_login = conf.get(backend, 'admin_login')
    admin_password = conf.get(backend, 'admin_password')

    import sievelib.managesieve

    sieveclient = sievelib.managesieve.Client(hostname, port, conf.debuglevel > 8)
    sieveclient.connect(None, None, True)
    result = sieveclient._plain_authentication(admin_login, admin_password, address)
    if not result:
        print "LOGIN FAILED??"
    
    sieveclient.authenticated = True

    result = sieveclient.listscripts()
    
    if result == None:
        print "No scripts"
        sys.exit(0)

    (active, scripts) = result

    print "%s (active)" % (active)
    for script in scripts:
        print script