Exemplo n.º 1
0
def is_email_exists(mail, conn=None) -> bool:
    # Return True if account is invalid or exist.
    if not iredutils.is_email(mail):
        return True

    mail = iredutils.strip_mail_ext_address(mail)

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        # `forwardings` table has email addr of mail user account and alias account.
        qr = conn.select('forwardings',
                         vars={'mail': mail},
                         what='address',
                         where='address=$mail',
                         limit=1)

        if qr:
            return True

        # Check `alias` for alias account which doesn't have any member.
        qr = conn.select('alias',
                         vars={'mail': mail},
                         what='address',
                         where='address=$mail',
                         limit=1)
        if qr:
            return True

        return False
    except Exception:
        return True
Exemplo n.º 2
0
def check_account_existence(mail, account_type='mail', conn=None):
    """Return tuple `(True,  )` if object exists, `(False, )` if not exists,
    (None, "<reason>") if something wrong happened.

    @param mail: full email address.
    @param account_type: must be one of: mail, user, alias, ml.
    @param conn: ldap connection cursor.
    """
    if account_type not in ['mail', 'user', 'alias', 'ml']:
        return (None, 'INVALID_ACCOUNT_TYPE')

    mail = str(mail).lower()
    mail = iredutils.strip_mail_ext_address(mail)

    if not iredutils.is_email(mail):
        return (None, 'INVALID_MAIL')

    # Filter used to search account.
    _filter = '(&'
    if account_type == 'mail':
        # mail user, mail alias, mailing list, mlmmj mailing list.
        _filter += '(|(objectClass=mailUser)(objectClass=mailList)(objectClass=mailAlias))'
        _filter += '(|(mail={})(shadowAddress={}))'.format(mail, mail)
    elif account_type == 'user':
        # mail user
        _filter += '(objectClass=mailUser)'
        _filter += '(|(mail={})(shadowAddress={}))'.format(mail, mail)

    _filter += ')'

    try:
        if not conn:
            _wrap = LDAPWrap()
            conn = _wrap.conn

        qr = conn.search_s(settings.ldap_basedn,
                           ldap.SCOPE_SUBTREE,
                           _filter,
                           ['dn'])

        if qr:
            return (True, )
        else:
            return (False, )
    except Exception as e:
        # Account 'EXISTS' (fake) if lookup failed.
        logger.error("Error while checking account existence: "
                     "mail={}, account_type={}, "
                     "error={}".format(mail, account_type, e))

        return (None, 'ERROR_WHILE_QUERYING_DB')
Exemplo n.º 3
0
def __is_account_exists(account, account_type, conn=None) -> bool:
    """Check whether mail alias account exists."""
    if account_type == 'domain':
        if not iredutils.is_domain(account):
            return True

        account = account.lower()
    else:
        if not iredutils.is_email(account):
            return False

        account = iredutils.strip_mail_ext_address(account)

    # {<account_type: [(<sql-table>, <sql-column-name>), ...]}
    _maps = {
        "domain": [
            ("domain", "domain"),
            ("alias_domain", "alias_domain"),
        ],
        "user": [("mailbox", "username")],
        "alias": [("alias", "address")],
        "ml": [("maillists", "address")],
    }

    if account_type not in _maps:
        return False

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        for (_table, _column) in _maps[account_type]:
            qr = conn.select(_table,
                             vars={'account': account},
                             what=_column,
                             where='%s=$account' % _column,
                             limit=1)

            if qr:
                return True
    except:
        log_traceback()
        return False

    return False
Exemplo n.º 4
0
def add(domain, form, conn=None):
    # Get domain name, username, cn.
    form_domain = form_utils.get_domain_name(form)
    if not (domain == form_domain):
        return (False, 'INVALID_DOMAIN_NAME')

    username = web.safestr(form.get('username')).strip().lower()
    mail = username + '@' + domain
    mail = iredutils.strip_mail_ext_address(mail)

    if not iredutils.is_auth_email(mail):
        return (False, 'INVALID_MAIL')

    if not conn:
        _wrap = LDAPWrap()
        conn = _wrap.conn

    _qr = ldap_lib_general.check_account_existence(mail=mail,
                                                   account_type='mail',
                                                   conn=conn)
    if _qr[0] is not False:
        return (False, 'ALREADY_EXISTS')

    # Get @domainAccountSetting.
    qr = ldap_lib_domain.get_profile(domain=domain, conn=conn)

    if not qr[0]:
        return qr

    domain_profile = qr[1]['ldif']
    domain_status = domain_profile.get('accountStatus', ['disabled'])[0]
    domainAccountSetting = ldaputils.get_account_setting_from_profile(
        domain_profile)

    # Check account number limit.
    _num_users = domainAccountSetting.get('numberOfUsers')
    if _num_users == '-1':
        return (False, 'NOT_ALLOWED')

    _pw_hash = form.get('password_hash', '')
    if _pw_hash:
        if not iredpwd.is_supported_password_scheme(_pw_hash):
            return (False, 'INVALID_PASSWORD_SCHEME')

        passwd_plain = ''
        passwd_hash = _pw_hash
    else:
        (min_pw_len,
         max_pw_len) = ldap_lib_general.get_domain_password_lengths(
             domain=domain,
             account_settings=domainAccountSetting,
             fallback_to_global_settings=False,
             conn=conn,
         )

        qr = form_utils.get_password(form=form,
                                     input_name='newpw',
                                     confirm_pw_input_name='confirmpw',
                                     min_passwd_length=min_pw_len,
                                     max_passwd_length=max_pw_len)

        if qr[0]:
            passwd_plain = qr[1]['pw_plain']
            passwd_hash = qr[1]['pw_hash']
        else:
            return qr

    cn = form_utils.get_name(form=form, input_name="cn")

    # Get preferred language.
    preferred_language = form_utils.get_language(form=form)
    if preferred_language not in iredutils.get_language_maps():
        preferred_language = None

    # Get user quota. Unit is MB.
    quota = form_utils.get_single_value(form=form,
                                        input_name='mailQuota',
                                        default_value=0,
                                        is_integer=True)

    quota = abs(quota)

    if quota == 0:
        # Get per-domain default user quota
        default_user_quota = ldap_lib_domain.get_default_user_quota(
            domain=domain, domain_account_setting=domainAccountSetting)

        quota = default_user_quota

    defaultStorageBaseDirectory = domainAccountSetting.get(
        'defaultStorageBaseDirectory', None)

    db_settings = iredutils.get_settings_from_db()
    # Get mailbox format and folder.
    _mailbox_format = form.get('mailboxFormat', '').lower()
    _mailbox_folder = form.get('mailboxFolder', '')
    if not iredutils.is_valid_mailbox_format(_mailbox_format):
        _mailbox_format = db_settings['mailbox_format']

    if not iredutils.is_valid_mailbox_folder(_mailbox_folder):
        _mailbox_folder = db_settings['mailbox_folder']

    # Get full maildir path
    _mailbox_maildir = form.get('maildir')

    # Get default mailing lists which set in domain accountSetting.
    ldif = iredldif.ldif_mailuser(
        domain=domain,
        username=username,
        cn=cn,
        passwd=passwd_hash,
        quota=quota,
        storage_base_directory=defaultStorageBaseDirectory,
        mailbox_format=_mailbox_format,
        mailbox_folder=_mailbox_folder,
        mailbox_maildir=_mailbox_maildir,
        language=preferred_language,
        domain_status=domain_status,
    )

    dn_user = ldaputils.rdn_value_to_user_dn(mail)

    # Store plain password in additional attribute
    if passwd_plain and settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR:
        ldif += [(settings.STORE_PLAIN_PASSWORD_IN_ADDITIONAL_ATTR,
                  [passwd_plain])]

    try:
        conn.add_s(dn_user, ldif)

        # Update count of accounts
        ldap_lib_general.update_num_domain_current_users(domain=domain,
                                                         increase=True,
                                                         conn=conn)

        log_activity(msg="Create user: %s." % (mail),
                     domain=domain,
                     event='create')

        return (True, )
    except ldap.ALREADY_EXISTS:
        return (False, 'ALREADY_EXISTS')
    except Exception as e:
        return (False, repr(e))
Exemplo n.º 5
0
def filter_existing_emails(mails, account_type=None, conn=None):
    """
    Remove non-existing addresses in given list, return a list of existing ones.

    :param mails: list of email addresses
    :param account_type: user, alias, maillist.
    :param conn: sql connection cursor
    """
    exist = []
    nonexist = []

    mails = [i for i in mails if iredutils.is_email(i)]

    if not mails:
        return {'exist': exist, 'nonexist': nonexist}

    # A dict with email addresses without and with mail extension.
    d = {}
    for i in mails:
        _addr_without_ext = iredutils.strip_mail_ext_address(i)
        d[_addr_without_ext] = i

    emails_without_ext = list(d.keys())

    # {<account_type>: {'table': <sql_table_name>, 'column': <sql_column_name>}}
    _tbl_column_maps = {
        'user': [("forwardings", "address"), ("mailbox", "username")],
        'alias': [("alias", "address")],
        'maillist': [("maillists", "address")],
    }

    if not conn:
        _wrap = SQLWrap()
        conn = _wrap.conn

    try:
        _tbl_and_columns = []
        if account_type:
            _tbl_and_columns += _tbl_column_maps[account_type]
        else:
            for v in list(_tbl_column_maps.values()):
                _tbl_and_columns += v

        for (_table, _column) in _tbl_and_columns:
            # Removing verified addresses to query less values for better SQL
            # query performance.
            _pending_emails = [i for i in emails_without_ext if i not in exist]
            if not _pending_emails:
                break

            qr = conn.select(_table,
                             vars={'mails': _pending_emails},
                             what='%s' % _column,
                             where='%s IN $mails' % _column,
                             group='%s' % _column)

            if qr:
                for row in qr:
                    _addr = str(row[_column]).lower()
                    exist.append(d[_addr])

        exist = list(set(exist))
        nonexist = [d[k] for k in d if k not in exist]
    except:
        log_traceback()

    return {'exist': exist, 'nonexist': nonexist}