Esempio n. 1
0
    def delete(self, mails):
        if mails is None or len(mails) == 0:
            return (False, "NO_ACCOUNT_SELECTED")

        result = {}

        for mail in mails:
            self.mail = web.safestr(mail)
            dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="admin")
            if dn[0] is False:
                return dn

            try:
                deltree.DelTree(self.conn, dn, ldap.SCOPE_SUBTREE)
                web.logger(msg="Delete admin: %s." % (self.mail,), event="delete")
            except ldap.NO_SUCH_OBJECT:
                # This is a mail user admin
                dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="user")
                try:
                    connutils = connUtils.Utils()
                    # Delete enabledService=domainadmin
                    connutils.addOrDelAttrValue(dn=dn, attr="enabledService", value="domainadmin", action="delete")

                    # Delete domainGlobalAdmin=yes
                    connutils.addOrDelAttrValue(dn=dn, attr="domainGlobalAdmin", value="yes", action="delete")
                    web.logger(msg="Delete admin: %s." % (self.mail), event="delete")
                except Exception, e:
                    result[self.mail] = str(e)
            except ldap.LDAPError, e:
                result[self.mail] = str(e)
Esempio n. 2
0
    def profile(self, domain, mail, accountType="user"):
        self.mail = web.safestr(mail)
        self.domain = self.mail.split("@", 1)[-1]

        if self.domain != domain:
            raise web.seeother("/domains?msg=PERMISSION_DENIED")

        self.filter = "(&(objectClass=mailUser)(mail=%s))" % (self.mail,)
        if accountType == "catchall":
            self.filter = "(&(objectClass=mailUser)(mail=@%s))" % (self.mail,)
        else:
            if not self.mail.endswith("@" + self.domain):
                raise web.seeother("/domains?msg=PERMISSION_DENIED")

        if attrs.RDN_USER == "mail":
            self.searchdn = ldaputils.convert_keyword_to_dn(self.mail, accountType=accountType)
            self.scope = ldap.SCOPE_BASE

            if self.searchdn[0] is False:
                return self.searchdn
        else:
            domain_dn = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")
            if domain_dn[0] is False:
                return domain_dn

            self.searchdn = attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn
            self.scope = ldap.SCOPE_SUBTREE

        try:
            self.user_profile = self.conn.search_s(self.searchdn, self.scope, self.filter, attrs.USER_ATTRS_ALL)
            return (True, self.user_profile)
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 3
0
    def enableOrDisableAccount(self, domain, mails, action, attr="accountStatus"):
        if mails is None or len(mails) == 0:
            return (False, "NO_ACCOUNT_SELECTED")

        self.mails = [str(v) for v in mails if iredutils.is_email(v) and str(v).endswith("@" + str(domain))]

        result = {}
        connutils = connUtils.Utils()
        for mail in self.mails:
            self.mail = web.safestr(mail)
            if not iredutils.is_email(self.mail):
                continue

            self.domain = self.mail.split("@")[-1]
            self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="user")
            if self.dn[0] is False:
                result[self.mail] = self.dn[1]
                continue

            try:
                connutils.enableOrDisableAccount(
                    domain=self.domain,
                    account=self.mail,
                    dn=self.dn,
                    action=web.safestr(action).strip().lower(),
                    accountTypeInLogger="user",
                )
            except ldap.LDAPError, e:
                result[self.mail] = str(e)
Esempio n. 4
0
    def deleteSingleUser(self, mail, deleteFromGroups=True):
        self.mail = web.safestr(mail)
        if not iredutils.is_email(self.mail):
            return (False, "INVALID_MAIL")

        # Get domain name of this account.
        self.domain = self.mail.split("@")[-1]

        # Get dn of mail user and domain.
        self.dnUser = ldaputils.convert_keyword_to_dn(self.mail, accountType="user")
        if self.dnUser[0] is False:
            return self.dnUser

        # Delete user object.
        try:
            # Delete single object.
            # self.conn.delete_s(self.dnUser)

            # Delete object and its subtree.
            deltree.DelTree(self.conn, self.dnUser, ldap.SCOPE_SUBTREE)

            if deleteFromGroups:
                self.deleteSingleUserFromGroups(self.mail)

            # Delete record from SQL database: real-time used quota.
            try:
                connUtils.deleteAccountFromUsedQuota([self.mail])
            except Exception, e:
                pass

            # Log delete action.
            web.logger(msg="Delete user: %s." % (self.mail), domain=self.domain, event="delete")
            return (True,)
Esempio n. 5
0
    def enableOrDisableAccount(self, mails, action, attr='accountStatus',):
        if mails is None or len(mails) == 0:
            return (False, 'NO_ACCOUNT_SELECTED')

        result = {}
        connutils = connUtils.Utils()
        for mail in mails:
            self.mail = web.safestr(mail).strip().lower()
            if not iredutils.is_email(self.mail):
                continue

            self.domain = self.mail.split('@')[-1]
            self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType='admin')
            if self.dn[0] is False:
                return self.dn

            try:
                connutils.enableOrDisableAccount(
                    domain=self.domain,
                    account=self.mail,
                    dn=self.dn,
                    action=web.safestr(action).strip().lower(),
                    accountTypeInLogger='admin',
                )
            except ldap.LDAPError, e:
                result[self.mail] = str(e)
Esempio n. 6
0
    def listAccounts(self, domain):
        self.domain = domain
        self.domainDN = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")
        if self.domainDN[0] is False:
            return self.domainDN

        try:
            # Use '(!([email protected]))' to hide catch-all account.
            self.users = self.conn.search_s(
                attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN,
                ldap.SCOPE_SUBTREE,
                "(&(objectClass=mailUser)(!(mail=@%s)))" % self.domain,
                attrs.USER_SEARCH_ATTRS,
            )

            connutils = connUtils.Utils()
            connutils.updateAttrSingleValue(self.domainDN, "domainCurrentUserNumber", len(self.users))

            return (True, self.users)
        except ldap.NO_SUCH_OBJECT:
            # self.conn.add_s(
            #        attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN,
            #        iredldif.ldif_group(attrs.GROUP_USERS),
            #        )
            return (False, "NO_SUCH_OBJECT")
        except ldap.SIZELIMIT_EXCEEDED:
            return (False, "EXCEEDED_LDAP_SERVER_SIZELIMIT")
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 7
0
    def getDomainDefaultUserQuota(self, domain, domainAccountSetting=None,):
        # Return 0 as unlimited.
        self.domain = web.safestr(domain)
        self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
        if self.dn[0] is False:
            return self.dn

        if domainAccountSetting is not None:
            if 'defaultQuota' in domainAccountSetting.keys():
                return int(domainAccountSetting['defaultQuota'])
            else:
                return 0
        else:
            try:
                result = self.conn.search_s(
                        self.dn,
                        ldap.SCOPE_BASE,
                        '(domainName=%s)' % self.domain,
                        ['domainName', 'accountSetting'],
                        )

                settings = ldaputils.getAccountSettingFromLdapQueryResult(result, key='domainName',)

                if 'defaultQuota' in settings[self.domain].keys():
                    return int(settings[self.domain]['defaultQuota'])
                else:
                    return 0
            except Exception:
                return 0
Esempio n. 8
0
    def add(self, data):
        # msg: {key: value}
        msg = {}
        self.domain = web.safestr(data.get('domainName', '')).strip().lower()

        # Check domain name.
        if not iredutils.is_domain(self.domain):
            return (False, 'INVALID_DOMAIN_NAME')

        # Check whether domain name already exist (domainName, domainAliasName).
        connutils = connUtils.Utils()
        if connutils.is_domain_exists(self.domain):
            return (False, 'ALREADY_EXISTS')

        self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
        if self.dn[0] is False:
            return self.dn

        self.cn = data.get('cn', None)
        ldif = iredldif.ldif_maildomain(domain=self.domain, cn=self.cn,)

        # Add domain dn.
        try:
            result = self.conn.add_s(self.dn, ldif)
            web.logger(msg="Create domain: %s." % (self.domain), domain=self.domain, event='create',)
        except ldap.ALREADY_EXISTS:
            msg[self.domain] = 'ALREADY_EXISTS'
        except ldap.LDAPError, e:
            msg[self.domain] = str(e)
Esempio n. 9
0
    def deleteSingleUserFromGroups(self, mail):
        self.mail = web.safestr(mail)
        if not iredutils.is_email(self.mail):
            return (False, "INVALID_MAIL")

        # Get domain name of this account.
        self.domain = self.mail.split("@")[-1]

        # Get dn of mail user and domain.
        self.dnUser = ldaputils.convert_keyword_to_dn(self.mail, accountType="user")
        self.dnDomain = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")

        if self.dnUser[0] is False:
            return self.dnUser

        if self.dnDomain[0] is False:
            return self.dnDomain

        try:
            # Get accounts which contains destination email.
            objsHasUser = self.conn.search_s(
                self.dnDomain, ldap.SCOPE_SUBTREE, self.getFilterOfDeleteUserFromGroups(self.mail), ["dn"]
            )

            if len(objsHasUser) >= 1:
                connutils = connUtils.Utils()
                for obj in objsHasUser:
                    if obj[0].endswith(attrs.DN_BETWEEN_ALIAS_AND_DOMAIN + self.dnDomain) or obj[0].endswith(
                        attrs.DN_BETWEEN_USER_AND_DOMAIN + self.dnDomain
                    ):
                        # Remove address from alias and user.
                        connutils.addOrDelAttrValue(
                            dn=obj[0], attr="mailForwardingAddress", value=self.mail, action="delete"
                        )
                    elif obj[0].endswith("ou=Externals," + self.domaindn):
                        # Remove address from external member list.
                        connutils.addOrDelAttrValue(dn=obj[0], attr="mail", value=self.mail, action="delete")
                    else:
                        pass
            else:
                pass

            return (True,)
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 10
0
    def getSizelimitFromAccountLists(self, accountList, sizelimit=50, curPage=1, domain=None, accountType=None):
        # Return a dict which contains:
        #   - totalAccounts: number of total accounts
        #   - accountList: list of accounts used to display in current page
        #   - totalPages: number of total pages show be showed in account list page.
        #   - totalQuota: number of domain quota size. Only available when accountType=='user'.

        # Initial a dict to set default values.
        result = {
            "totalAccounts": 0,  # Integer
            "accountList": [],  # List
            "totalPages": 0,  # Integer
            "totalQuota": 0,  # Integer
            "currentQuota": {},  # Dict
        }

        # Get total accounts.
        totalAccounts = len(accountList)
        result["totalAccounts"] = totalAccounts

        # Get number of actual pages.
        if totalAccounts % sizelimit == 0:
            totalPages = totalAccounts / sizelimit
        else:
            totalPages = (totalAccounts / sizelimit) + 1
        result["totalPages"] = totalPages

        if curPage >= totalPages:
            curPage = totalPages

        # Sort accounts in place.
        if isinstance(accountList, list):
            accountList.sort()
        else:
            pass

        # Get total domain mailbox quota.
        if accountType == "user":
            counter = 0
            for i in accountList:
                quota = i[1].get("mailQuota", ["0"])[0]
                if quota.isdigit():
                    result["totalQuota"] += int(quota)
                    counter += 1

            # Update number of current domain quota size in LDAP (@attrs.ATTR_DOMAIN_CURRENT_QUOTA_SIZE).
            if domain is not None:
                # Update number of current domain quota size in LDAP.
                try:
                    dnDomain = ldaputils.convert_keyword_to_dn(domain, accountType="domain")
                    self.updateAttrSingleValue(
                        dn=dnDomain, attr=attrs.ATTR_DOMAIN_CURRENT_QUOTA_SIZE, value=str(result["totalQuota"])
                    )
                except Exception, e:
                    pass
Esempio n. 11
0
    def update(self, profile_type, domain, data):
        self.profile_type = web.safestr(profile_type)
        self.domain = web.safestr(domain)
        self.domaindn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
        if self.domaindn[0] is False:
            return self.domaindn

        connutils = connUtils.Utils()
        self.accountSetting = []
        mod_attrs = []

        # Allow normal admin to update profiles.
        if self.profile_type == 'general':
            cn = data.get('cn', None)
            mod_attrs += ldaputils.getSingleModAttr(attr='cn', value=cn, default=self.domain)

        # Allow global admin to update profiles.
        if session.get('domainGlobalAdmin') is True:
            if self.profile_type == 'general':
                # Get accountStatus.
                if 'accountStatus' in data.keys():
                    accountStatus = 'active'
                else:
                    accountStatus = 'disabled'

                mod_attrs += [(ldap.MOD_REPLACE, 'accountStatus', accountStatus)]

        try:
            dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
            if dn[0] is False:
                return dn

            self.conn.modify_s(dn, mod_attrs)
            web.logger(msg="Update domain profile: %s (%s)." % (domain, profile_type),
                       domain=domain,
                       event='update',
                      )
            return (True,)
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 12
0
    def update(self, profile_type, mail, data):
        self.profile_type = web.safestr(profile_type)
        self.mail = web.safestr(mail)
        self.username, self.domain = self.mail.split('@', 1)

        if session.get('domainGlobalAdmin') is not True and session.get('username') != self.mail:
            # Don't allow to view/update other admins' profile.
            return (False, 'PERMISSION_DENIED')

        self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType='admin')
        if self.dn[0] is False:
            return self.dn

        mod_attrs = []
        if self.profile_type == 'general':
            # Get preferredLanguage.
            lang = web.safestr(data.get('preferredLanguage', 'en_US'))
            mod_attrs += [(ldap.MOD_REPLACE, 'preferredLanguage', lang)]

            # Get cn.
            cn = data.get('cn', None)
            mod_attrs += ldaputils.getSingleModAttr(attr='cn',
                                                    value=cn,
                                                    default=self.username)

            first_name = data.get('first_name', '')
            mod_attrs += ldaputils.getSingleModAttr(attr='givenName',
                                                    value=first_name,
                                                    default=self.username)

            last_name = data.get('last_name', '')
            mod_attrs += ldaputils.getSingleModAttr(attr='sn',
                                                    value=last_name,
                                                    default=self.username)

            # Get accountStatus.
            if 'accountStatus' in data.keys():
                accountStatus = 'active'
            else:
                accountStatus = 'disabled'

            mod_attrs += [(ldap.MOD_REPLACE, 'accountStatus', accountStatus)]

            try:
                # Modify profiles.
                self.conn.modify_s(self.dn, mod_attrs)
                if session.get('username') == self.mail and \
                   session.get('lang', 'en_US') != lang:
                    session['lang'] = lang
            except ldap.LDAPError, e:
                return (False, ldaputils.getExceptionDesc(e))
Esempio n. 13
0
    def profile(self, mail, attributes=attrs.ADMIN_ATTRS_ALL):
        self.mail = web.safestr(mail)
        self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="admin")
        if self.dn[0] is False:
            return self.dn

        try:
            self.admin_profile = self.conn.search_s(
                self.dn, ldap.SCOPE_BASE, "(&(objectClass=mailAdmin)(mail=%s))" % self.mail, attributes
            )
            return (True, self.admin_profile)
        except ldap.NO_SUCH_OBJECT:
            return (False, "NO_SUCH_OBJECT")
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 14
0
    def getDnWithKeyword(self, value, accountType="user"):
        self.keyword = web.safestr(value)

        if accountType == "user":
            if attrs.RDN_USER == "mail":
                if not iredutils.is_email(self.keyword):
                    return False
                return ldaputils.convert_keyword_to_dn(self.keyword, accountType="user")
            else:
                self.domain = self.keyword.split("@", 1)[-1]
                self.dnOfDomain = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")
                try:
                    result = self.conn.search_s(
                        attrs.DN_BETWEEN_USER_AND_DOMAIN + self.dnOfDomain,
                        ldap.SCOPE_SUBTREE,
                        "(&(objectClass=mailUser)(mail=%s))" % (self.keyword),
                    )
                    if len(result) == 1:
                        self.dn = result[0][0]
                        return self.dn
                    else:
                        return False
                except Exception, e:
                    return False
Esempio n. 15
0
 def is_domainAdmin(self, domain, admin=session.get('username'),):
     dn = ldaputils.convert_keyword_to_dn(domain, accountType='domain')
     try:
         result = self.conn.search_s(
             dn,
             ldap.SCOPE_BASE,
             "(&(%s=%s)(domainAdmin=%s))" % (attrs.RDN_DOMAIN, domain, admin),
             ['dn', 'domainAdmin'],
         )
         if len(result) >= 1:
             return True
         else:
             return False
     except Exception:
         return False
Esempio n. 16
0
    def getDomainAdmins(self, domain):
        domain = web.safestr(domain)
        dn = ldaputils.convert_keyword_to_dn(domain, accountType='domain')
        if dn[0] is False:
            return dn

        try:
            self.domainAdmins = self.conn.search_s(
                    dn,
                    ldap.SCOPE_BASE,
                    '(&(objectClass=mailDomain)(domainName=%s))' % domain,
                    ['domainAdmin'],
                    )
            return self.domainAdmins
        except Exception, e:
            return str(e)
Esempio n. 17
0
    def update(self, profile_type, mail, data):
        self.profile_type = web.safestr(profile_type)
        self.mail = web.safestr(mail)
        self.username, self.domain = self.mail.split("@", 1)

        if session.get("domainGlobalAdmin") is not True and session.get("username") != self.mail:
            # Don't allow to view/update other admins' profile.
            return (False, "PERMISSION_DENIED")

        self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="admin")
        if self.dn[0] is False:
            return self.dn

        mod_attrs = []
        if self.profile_type == "general":
            # Get preferredLanguage.
            lang = web.safestr(data.get("preferredLanguage", "en_US"))
            mod_attrs += [(ldap.MOD_REPLACE, "preferredLanguage", lang)]

            # Get cn.
            cn = data.get("cn", None)
            mod_attrs += ldaputils.getSingleModAttr(attr="cn", value=cn, default=self.username)

            first_name = data.get("first_name", "")
            mod_attrs += ldaputils.getSingleModAttr(attr="givenName", value=first_name, default=self.username)

            last_name = data.get("last_name", "")
            mod_attrs += ldaputils.getSingleModAttr(attr="sn", value=last_name, default=self.username)

            # Get accountStatus.
            if "accountStatus" in data.keys():
                accountStatus = "active"
            else:
                accountStatus = "disabled"

            mod_attrs += [(ldap.MOD_REPLACE, "accountStatus", accountStatus)]

            try:
                # Modify profiles.
                self.conn.modify_s(self.dn, mod_attrs)
                if session.get("username") == self.mail and session.get("lang", "en_US") != lang:
                    session["lang"] = lang
            except ldap.LDAPError, e:
                return (False, ldaputils.getExceptionDesc(e))
Esempio n. 18
0
    def add(self, data):
        self.cn = data.get("cn")
        self.mail = web.safestr(data.get("mail")).strip().lower()

        if not iredutils.is_email(self.mail):
            return (False, "INVALID_MAIL")

        self.domainGlobalAdmin = web.safestr(data.get("domainGlobalAdmin", "no"))
        if self.domainGlobalAdmin not in ["yes", "no"]:
            self.domainGlobalAdmin = "no"

        self.preferredLanguage = web.safestr(data.get("preferredLanguage", "en_US"))

        # Check password.
        self.newpw = web.safestr(data.get("newpw"))
        self.confirmpw = web.safestr(data.get("confirmpw"))

        result = iredutils.verify_new_password(self.newpw, self.confirmpw)
        if result[0] is True:
            self.passwd = iredutils.generate_password_hash(result[1])
        else:
            return result

        ldif = iredldif.ldif_mailadmin(
            mail=self.mail,
            passwd=self.passwd,
            cn=self.cn,
            preferredLanguage=self.preferredLanguage,
            domainGlobalAdmin=self.domainGlobalAdmin,
        )

        self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="admin")
        if self.dn[0] is False:
            return self.dn

        try:
            self.conn.add_s(self.dn, ldif)
            web.logger(msg="Create admin: %s." % (self.mail), event="create")
            return (True,)
        except ldap.ALREADY_EXISTS:
            return (False, "ALREADY_EXISTS")
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 19
0
    def add(self, data):
        self.cn = data.get('cn')
        self.mail = web.safestr(data.get('mail')).strip().lower()

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

        self.domainGlobalAdmin = web.safestr(data.get('domainGlobalAdmin', 'no'))
        if self.domainGlobalAdmin not in ['yes', 'no', ]:
            self.domainGlobalAdmin = 'no'

        self.preferredLanguage = web.safestr(data.get('preferredLanguage', 'en_US'))

        # Check password.
        self.newpw = web.safestr(data.get('newpw'))
        self.confirmpw = web.safestr(data.get('confirmpw'))

        result = iredutils.verify_new_password(self.newpw, self.confirmpw)
        if result[0] is True:
            self.passwd = ldaputils.generate_ldap_password(result[1])
        else:
            return result

        ldif = iredldif.ldif_mailadmin(
                mail=self.mail,
                passwd=self.passwd,
                cn=self.cn,
                preferredLanguage=self.preferredLanguage,
                domainGlobalAdmin=self.domainGlobalAdmin,
                )

        self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType='admin')
        if self.dn[0] is False:
            return self.dn

        try:
            self.conn.add_s(self.dn, ldif)
            web.logger(msg="Create admin: %s." % (self.mail), event='create',)
            return (True,)
        except ldap.ALREADY_EXISTS:
            return (False, 'ALREADY_EXISTS')
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 20
0
    def profile(self, domain):
        self.domain = web.safestr(domain)
        self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
        if self.dn[0] is False:
            return self.dn

        try:
            self.domain_profile = self.conn.search_s(
                self.dn,
                ldap.SCOPE_BASE,
                '(&(objectClass=mailDomain)(domainName=%s))' % self.domain,
                attrs.DOMAIN_ATTRS_ALL,
            )
            if len(self.domain_profile) == 1:
                return (True, self.domain_profile)
            else:
                return (False, 'NO_SUCH_DOMAIN')
        except ldap.NO_SUCH_OBJECT:
            return (False, 'NO_SUCH_OBJECT')
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 21
0
    def getNumberOfCurrentAccountsUnderDomain(self, domain, accountType="user", filter=None):
        # accountType in ['user', 'list', 'alias',]
        self.domain = web.safestr(domain)
        self.domaindn = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")

        if filter is not None:
            self.searchdn = self.domaindn
            self.filter = filter
        else:
            if accountType == "user":
                self.searchdn = attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domaindn
                self.filter = "(&(objectClass=mailUser)(!(mail=@%s)))" % self.domain
            else:
                self.searchdn = self.domaindn
                self.filter = "(&(objectClass=mailUser)(!(mail=@%s)))" % self.domain

        try:
            result = self.conn.search_s(self.searchdn, ldap.SCOPE_SUBTREE, self.filter, ["dn"])
            return (True, len(result))
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 22
0
    def getAvailableDomainNames(self, domain):
        """Get list of domainName and domainAliasName by quering domainName.

        >>> getAvailableDomainNames(domain='example.com')
        (True, ['example.com', 'aliasdomain01.com', 'aliasdomain02.com', ...])
        """
        domain = web.safestr(domain).strip().lower()
        if not iredutils.is_domain(domain):
            return (False, "INVALID_DOMAIN_NAME")

        dn = ldaputils.convert_keyword_to_dn(domain, accountType="domain")

        try:
            result = self.conn.search_s(
                dn,
                ldap.SCOPE_BASE,
                "(&(objectClass=mailDomain)(domainName=%s))" % domain,
                ["domainName", "domainAliasName"],
            )
            return (True, result[0][1].get("domainName", []) + result[0][1].get("domainAliasName", []))
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 23
0
    def enableOrDisableAccount(self, domains, action, attr='accountStatus',):
        if domains is None or len(domains) == 0:
            return (False, 'NO_DOMAIN_SELECTED')

        result = {}
        connutils = connUtils.Utils()
        for domain in domains:
            self.domain = web.safestr(domain)
            self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
            if self.dn[0] is False:
                return self.dn

            try:
                connutils.enableOrDisableAccount(
                    domain=self.domain,
                    account=self.domain,
                    dn=self.dn,
                    action=web.safestr(action).strip().lower(),
                    accountTypeInLogger='domain',
                )
            except ldap.LDAPError, e:
                result[self.domain] = str(e)
Esempio n. 24
0
    def delete(self, domain, mails=[]):
        if mails is None or len(mails) == 0:
            return (False, "NO_ACCOUNT_SELECTED")

        self.domain = web.safestr(domain)
        self.mails = [str(v) for v in mails if iredutils.is_email(v) and str(v).endswith("@" + self.domain)]
        if not len(self.mails) > 0:
            return (False, "INVALID_MAIL")

        self.domaindn = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")
        if self.domaindn[0] is False:
            return self.domaindn

        if not iredutils.is_domain(self.domain):
            return (False, "INVALID_DOMAIN_NAME")

        result = {}
        for mail in self.mails:
            self.mail = web.safestr(mail)

            try:
                # Delete user object (ldap.SCOPE_BASE).
                self.deleteSingleUser(self.mail)

                # Delete user object and whole sub-tree.
                # Get dn of mail user and domain.
                """
                self.userdn = ldaputils.convert_keyword_to_dn(self.mail, accountType='user')
                deltree.DelTree(self.conn, self.userdn, ldap.SCOPE_SUBTREE)

                # Log delete action.
                web.logger(
                    msg="Delete user: %s." % (self.mail),
                    domain=self.mail.split('@')[1],
                    event='delete',
                )
                """
            except ldap.LDAPError, e:
                result[self.mail] = ldaputils.getExceptionDesc(e)
Esempio n. 25
0
    def profile(self, domain):
        self.domain = web.safestr(domain)
        self.dn = ldaputils.convert_keyword_to_dn(self.domain,
                                                  accountType='domain')
        if self.dn[0] is False:
            return self.dn

        try:
            self.domain_profile = self.conn.search_s(
                self.dn,
                ldap.SCOPE_BASE,
                '(&(objectClass=mailDomain)(domainName=%s))' % self.domain,
                attrs.DOMAIN_ATTRS_ALL,
            )
            if len(self.domain_profile) == 1:
                return (True, self.domain_profile)
            else:
                return (False, 'NO_SUCH_DOMAIN')
        except ldap.NO_SUCH_OBJECT:
            return (False, 'NO_SUCH_OBJECT')
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 26
0
    def enableOrDisableAccount(self, domains, action, attr='accountStatus',):
        if domains is None or len(domains) == 0:
            return (False, 'NO_DOMAIN_SELECTED')

        result = {}
        connutils = connUtils.Utils()
        for domain in domains:
            self.domain = web.safestr(domain)
            self.dn = ldaputils.convert_keyword_to_dn(self.domain, accountType='domain')
            if self.dn[0] is False:
                return self.dn

            try:
                connutils.enableOrDisableAccount(
                    domain=self.domain,
                    account=self.domain,
                    dn=self.dn,
                    action=web.safestr(action).strip().lower(),
                    accountTypeInLogger='domain',
                )
            except ldap.LDAPError, e:
                result[self.domain] = str(e)
Esempio n. 27
0
    def enableOrDisableAccount(
        self,
        domain,
        mails,
        action,
        attr='accountStatus',
    ):
        if mails is None or len(mails) == 0:
            return (False, 'NO_ACCOUNT_SELECTED')

        self.mails = [
            str(v) for v in mails
            if iredutils.is_email(v) and str(v).endswith('@' + str(domain))
        ]

        result = {}
        connutils = connUtils.Utils()
        for mail in self.mails:
            self.mail = web.safestr(mail)
            if not iredutils.is_email(self.mail):
                continue

            self.domain = self.mail.split('@')[-1]
            self.dn = ldaputils.convert_keyword_to_dn(self.mail,
                                                      accountType='user')
            if self.dn[0] is False:
                result[self.mail] = self.dn[1]
                continue

            try:
                connutils.enableOrDisableAccount(
                    domain=self.domain,
                    account=self.mail,
                    dn=self.dn,
                    action=web.safestr(action).strip().lower(),
                    accountTypeInLogger='user',
                )
            except ldap.LDAPError, e:
                result[self.mail] = str(e)
Esempio n. 28
0
    def getAvailableDomainNames(self, domain):
        '''Get list of domainName and domainAliasName by quering domainName.

        >>> getAvailableDomainNames(domain='example.com')
        (True, ['example.com', 'aliasdomain01.com', 'aliasdomain02.com', ...])
        '''
        domain = web.safestr(domain).strip().lower()
        if not iredutils.is_domain(domain):
            return (False, 'INVALID_DOMAIN_NAME')

        dn = ldaputils.convert_keyword_to_dn(domain, accountType='domain')

        try:
            result = self.conn.search_s(
                dn,
                ldap.SCOPE_BASE,
                '(&(objectClass=mailDomain)(domainName=%s))' % domain,
                ['domainName', 'domainAliasName'],
            )
            return (True, result[0][1].get('domainName', []) +
                    result[0][1].get('domainAliasName', []))
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 29
0
    def delete(self, domains=[]):
        if not isinstance(domains, list):
            return (False, 'INVALID_DOMAIN_NAME')

        domains = [str(v).lower()
                   for v in domains
                   if iredutils.is_domain(v)
                  ]

        if not domains:
            return (True,)

        msg = {}
        for domain in domains:
            dn = ldaputils.convert_keyword_to_dn(web.safestr(domain), accountType='domain')
            if dn[0] is False:
                return dn

            try:
                deltree.DelTree(self.conn, dn, ldap.SCOPE_SUBTREE)
                web.logger(msg="Delete domain: %s." % (domain), domain=domain, event='delete',)
            except ldap.LDAPError, e:
                msg[domain] = str(e)
Esempio n. 30
0
    def getDomainCurrentQuotaSizeFromLDAP(self, domain):
        self.domain = web.safestr(domain).strip().lower()
        if not iredutils.is_domain(self.domain):
            return (False, "INVALID_DOMAIN_NAME")

        self.domainDN = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")

        # Initial @domainCurrentQuotaSize
        self.domainCurrentQuotaSize = 0

        try:
            # Use '(!([email protected]))' to hide catch-all account.
            self.users = self.conn.search_s(
                attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN,
                ldap.SCOPE_SUBTREE,
                "(&(objectClass=mailUser)(!(mail=@%s)))" % self.domain,
                attrs.USER_SEARCH_ATTRS,
            )

            # Update @domainCurrentUserNumber
            self.updateAttrSingleValue(self.domainDN, "domainCurrentUserNumber", len(self.users))

            for i in self.users:
                quota = i[1].get("mailQuota", ["0"])[0]
                if quota.isdigit():
                    self.domainCurrentQuotaSize += int(quota)
            return (True, self.domainCurrentQuotaSize)
        except ldap.NO_SUCH_OBJECT:
            # self.conn.add_s(
            #        attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN,
            #        iredldif.ldif_group(attrs.GROUP_USERS),
            #        )
            return (False, "NO_SUCH_OBJECT")
        except ldap.SIZELIMIT_EXCEEDED:
            return (False, "EXCEEDED_LDAP_SERVER_SIZELIMIT")
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 31
0
    def getDomainDefaultUserQuota(
        self,
        domain,
        domainAccountSetting=None,
    ):
        # Return 0 as unlimited.
        self.domain = web.safestr(domain)
        self.dn = ldaputils.convert_keyword_to_dn(self.domain,
                                                  accountType='domain')
        if self.dn[0] is False:
            return self.dn

        if domainAccountSetting is not None:
            if 'defaultQuota' in domainAccountSetting.keys():
                return int(domainAccountSetting['defaultQuota'])
            else:
                return 0
        else:
            try:
                result = self.conn.search_s(
                    self.dn,
                    ldap.SCOPE_BASE,
                    '(domainName=%s)' % self.domain,
                    ['domainName', 'accountSetting'],
                )

                settings = ldaputils.getAccountSettingFromLdapQueryResult(
                    result,
                    key='domainName',
                )

                if 'defaultQuota' in settings[self.domain].keys():
                    return int(settings[self.domain]['defaultQuota'])
                else:
                    return 0
            except Exception:
                return 0
Esempio n. 32
0
    def add(self, data):
        # msg: {key: value}
        msg = {}
        self.domain = web.safestr(data.get('domainName', '')).strip().lower()

        # Check domain name.
        if not iredutils.is_domain(self.domain):
            return (False, 'INVALID_DOMAIN_NAME')

        # Check whether domain name already exist (domainName, domainAliasName).
        connutils = connUtils.Utils()
        if connutils.is_domain_exists(self.domain):
            return (False, 'ALREADY_EXISTS')

        self.dn = ldaputils.convert_keyword_to_dn(self.domain,
                                                  accountType='domain')
        if self.dn[0] is False:
            return self.dn

        self.cn = data.get('cn', None)
        ldif = iredldif.ldif_maildomain(
            domain=self.domain,
            cn=self.cn,
        )

        # Add domain dn.
        try:
            result = self.conn.add_s(self.dn, ldif)
            web.logger(
                msg="Create domain: %s." % (self.domain),
                domain=self.domain,
                event='create',
            )
        except ldap.ALREADY_EXISTS:
            msg[self.domain] = 'ALREADY_EXISTS'
        except ldap.LDAPError, e:
            msg[self.domain] = str(e)
Esempio n. 33
0
    def getDomainCurrentQuotaSizeFromLDAP(self, domain):
        self.domain = web.safestr(domain).strip().lower()
        if not iredutils.is_domain(self.domain):
            return (False, 'INVALID_DOMAIN_NAME')

        self.domainDN = ldaputils.convert_keyword_to_dn(self.domain,
                                                        accountType='domain')

        # Initial @domainCurrentQuotaSize
        self.domainCurrentQuotaSize = 0

        try:
            # Use '(!([email protected]))' to hide catch-all account.
            self.users = self.conn.search_s(
                attrs.DN_BETWEEN_USER_AND_DOMAIN + self.domainDN,
                ldap.SCOPE_SUBTREE,
                '(&(objectClass=mailUser)(!(mail=@%s)))' % self.domain,
                attrs.USER_SEARCH_ATTRS,
            )

            # Update @domainCurrentUserNumber
            self.updateAttrSingleValue(self.domainDN,
                                       'domainCurrentUserNumber',
                                       len(self.users))

            for i in self.users:
                quota = i[1].get('mailQuota', ['0'])[0]
                if quota.isdigit():
                    self.domainCurrentQuotaSize += int(quota)
            return (True, self.domainCurrentQuotaSize)
        except ldap.NO_SUCH_OBJECT:
            return (False, 'NO_SUCH_OBJECT')
        except ldap.SIZELIMIT_EXCEEDED:
            return (False, 'EXCEEDED_LDAP_SERVER_SIZELIMIT')
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
else:
    usage()

total = len(users)
logger.info('%d users in total.' % total)

count = 1
if backend == 'ldap':
    import ldap
    from libs.ldaplib.ldaputils import convert_keyword_to_dn
    conn = get_db_conn('ldap')

    for (_email, _pw) in users:
        logger.info('(%d/%d) Updating %s' % (count, total, _email))

        dn = convert_keyword_to_dn(_email, accountType='user')
        pw_hash = generate_password_hash(_pw)
        mod_attrs = [(ldap.MOD_REPLACE, 'userPassword', [pw_hash])]
        try:
            conn.modify_s(dn, mod_attrs)
        except Exception, e:
            print '<<< ERROR >>>', e
elif backend in ['mysql', 'pgsql']:
    conn = get_db_conn('vmail')
    for (_email, _pw) in users:
        logger.info('(%d/%d) Updating %s' % (count, total, _email))
        pw_hash = generate_password_hash(_pw)
        conn.update('mailbox',
                    password=pw_hash,
                    where="username='******'" % _email)
Esempio n. 35
0
    def delete(self, domains=None, keep_mailbox_days=0):
        if not domains:
            return (False, 'INVALID_DOMAIN_NAME')

        domains = [str(v).lower() for v in domains if iredutils.is_domain(v)]

        if not domains:
            return (True, )

        msg = {}
        for domain in domains:
            dn = ldaputils.convert_keyword_to_dn(web.safestr(domain),
                                                 accountType='domain')
            if dn[0] is False:
                return dn

            # Log maildir path in SQL table.
            try:
                qr = self.conn.search_s(attrs.DN_BETWEEN_USER_AND_DOMAIN + dn,
                                        ldap.SCOPE_ONELEVEL,
                                        "(objectClass=mailUser)",
                                        ['mail', 'homeDirectory'])

                if keep_mailbox_days == 0:
                    keep_mailbox_days = 36500

                # Convert keep days to string
                _now_in_seconds = time.time()
                _days_in_seconds = _now_in_seconds + (keep_mailbox_days * 24 *
                                                      60 * 60)
                sql_keep_days = time.strftime(
                    '%Y-%m-%d', time.strptime(time.ctime(_days_in_seconds)))

                v = []
                for obj in qr:
                    deleted_mail = obj[1].get('mail')[0]
                    deleted_maildir = obj[1].get('homeDirectory', [''])[0]
                    v += [{
                        'maildir': deleted_maildir,
                        'username': deleted_mail,
                        'domain': domain,
                        'admin': session.get('username'),
                        'delete_date': sql_keep_days
                    }]

                if v:
                    web.admindb.multiple_insert('deleted_mailboxes', values=v)
            except:
                pass

            try:
                connUtils.delete_ldap_tree(dn=dn, conn=self.conn)
                web.logger(
                    msg="Delete domain: %s." % (domain),
                    domain=domain,
                    event='delete',
                )
            except ldap.LDAPError as e:
                msg[domain] = str(e)

        # Delete real-time mailbox quota.
        try:
            web.admindb.query(
                'DELETE FROM %s WHERE %s' %
                (settings.SQL_TBL_USED_QUOTA,
                 web.sqlors('username LIKE ', ['%@' + d for d in domains])))
        except:
            pass

        if msg == {}:
            return (True, )
        else:
            return (False, ldaputils.getExceptionDesc(msg))
Esempio n. 36
0
    def add(self, domain, data):
        # Get domain name, username, cn.
        self.domain = web.safestr(data.get("domainName")).strip().lower()
        self.username = web.safestr(data.get("username")).strip().lower()
        self.mail = self.username + "@" + self.domain
        self.groups = data.get("groups", [])

        if not iredutils.is_domain(self.domain) or not iredutils.is_email(self.mail):
            return (False, "MISSING_DOMAIN_OR_USERNAME")

        # Check account existing.
        connutils = connUtils.Utils()
        if connutils.isAccountExists(domain=self.domain, mail=self.mail):
            return (False, "ALREADY_EXISTS")

        # Get @domainAccountSetting.
        domainLib = domainlib.Domain()
        result_domain_profile = domainLib.profile(domain=self.domain)

        # Initial parameters.
        domainAccountSetting = {}
        self.aliasDomains = []

        if result_domain_profile[0] is not True:
            return (False, result_domain_profile[1])

        domainProfile = result_domain_profile[1]
        domainAccountSetting = ldaputils.getAccountSettingFromLdapQueryResult(domainProfile, key="domainName").get(
            self.domain, {}
        )
        self.aliasDomains = domainProfile[0][1].get("domainAliasName", [])

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

        # Check password.
        self.newpw = web.safestr(data.get("newpw"))
        self.confirmpw = web.safestr(data.get("confirmpw"))

        result = iredutils.verify_new_password(
            self.newpw,
            self.confirmpw,
            min_passwd_length=domainAccountSetting.get("minPasswordLength", "0"),
            max_passwd_length=domainAccountSetting.get("maxPasswordLength", "0"),
        )
        if result[0] is True:
            if "storePasswordInPlainText" in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT:
                self.passwd = iredutils.generate_password_hash(result[1], pwscheme="PLAIN")
            else:
                self.passwd = iredutils.generate_password_hash(result[1])
        else:
            return result

        # Get display name.
        self.cn = data.get("cn")

        # Get user quota. Unit is MB.
        # 0 or empty is not allowed if domain quota is set, set to
        # @defaultUserQuota or @domainSpareQuotaSize

        # Initial final mailbox quota.
        self.quota = 0

        # Get mail quota from web form.
        defaultUserQuota = domainLib.getDomainDefaultUserQuota(self.domain, domainAccountSetting)
        self.mailQuota = str(data.get("mailQuota")).strip()
        if self.mailQuota.isdigit():
            self.mailQuota = int(self.mailQuota)
        else:
            self.mailQuota = defaultUserQuota

        # 0 means unlimited.
        domainQuotaSize, domainQuotaUnit = domainAccountSetting.get("domainQuota", "0:GB").split(":")
        if int(domainQuotaSize) == 0:
            # Unlimited.
            self.quota = self.mailQuota
        else:
            # Get domain quota, convert to MB.
            if domainQuotaUnit == "TB":
                domainQuota = int(domainQuotaSize) * 1024 * 1024  # TB
            elif domainQuotaUnit == "GB":
                domainQuota = int(domainQuotaSize) * 1024  # GB
            else:
                domainQuota = int(domainQuotaSize)  # MB

            result = connutils.getDomainCurrentQuotaSizeFromLDAP(domain=self.domain)
            if result[0] is True:
                domainCurrentQuotaSize = result[1]
            else:
                domainCurrentQuotaSize = 0

            # Spare quota.
            domainSpareQuotaSize = domainQuota - domainCurrentQuotaSize / (1024 * 1024)

            if domainSpareQuotaSize <= 0:
                return (False, "EXCEEDED_DOMAIN_QUOTA_SIZE")

            # Get FINAL mailbox quota.
            if self.mailQuota == 0:
                self.quota = domainSpareQuotaSize
            else:
                if domainSpareQuotaSize > self.mailQuota:
                    self.quota = self.mailQuota
                else:
                    self.quota = domainSpareQuotaSize

        # Get default groups.
        self.groups = [
            web.safestr(v) for v in domainAccountSetting.get("defaultList", "").split(",") if iredutils.is_email(v)
        ]

        self.defaultStorageBaseDirectory = domainAccountSetting.get("defaultStorageBaseDirectory", None)

        # Get default mail lists which set in domain accountSetting.
        ldif = iredldif.ldif_mailuser(
            domain=self.domain,
            aliasDomains=self.aliasDomains,
            username=self.username,
            cn=self.cn,
            passwd=self.passwd,
            quota=self.quota,
            groups=self.groups,
            storageBaseDirectory=self.defaultStorageBaseDirectory,
        )

        domain_dn = ldaputils.convert_keyword_to_dn(self.domain, accountType="domain")
        if domain_dn[0] is False:
            return domain_dn

        if attrs.RDN_USER == "mail":
            self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType="user")
            if self.dn[0] is False:
                return self.dn

        elif attrs.RDN_USER == "cn":
            self.dn = "cn=" + self.cn + "," + attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn
        elif attrs.RDN_USER == "uid":
            self.dn = "uid=" + self.username + "," + attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn
        else:
            return (False, "UNSUPPORTED_USER_RDN")

        try:
            self.conn.add_s(ldap.filter.escape_filter_chars(self.dn), ldif)
            web.logger(msg="Create user: %s." % (self.mail), domain=self.domain, event="create")
            return (True,)
        except ldap.ALREADY_EXISTS:
            return (False, "ALREADY_EXISTS")
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 37
0
    def deleteSingleUser(self,
                         mail,
                         deleteFromGroups=True,
                         keep_mailbox_days=0):
        self.mail = web.safestr(mail)
        if not iredutils.is_email(self.mail):
            return (False, 'INVALID_MAIL')

        # Get domain name of this account.
        self.domain = self.mail.split('@')[-1]

        # Get dn of mail user and domain.
        self.dnUser = ldaputils.convert_keyword_to_dn(self.mail,
                                                      accountType='user')
        if self.dnUser[0] is False:
            return self.dnUser

        # Log maildir path in SQL table.
        try:
            qr_profile = self.profile(domain=self.domain, mail=self.mail)
            if qr_profile[0]:
                user_profile = qr_profile[1][0][1]
            else:
                return qr_profile

            if 'homeDirectory' in user_profile:
                maildir = user_profile.get('homeDirectory', [''])[0]
            else:
                storageBaseDirectory = user_profile.get(
                    'storageBaseDirectory', [''])[0]
                mailMessageStore = user_profile.get('mailMessageStore',
                                                    [''])[0]
                maildir = os.path.join(storageBaseDirectory, mailMessageStore)

            if keep_mailbox_days == 0:
                keep_mailbox_days = 36500

            # Convert keep days to string
            _now_in_seconds = time.time()
            _days_in_seconds = _now_in_seconds + (keep_mailbox_days * 24 * 60 *
                                                  60)
            sql_keep_days = time.strftime(
                '%Y-%m-%d', time.strptime(time.ctime(_days_in_seconds)))

            web.admindb.insert('deleted_mailboxes',
                               maildir=maildir,
                               username=self.mail,
                               domain=self.domain,
                               admin=session.get('username'),
                               delete_date=sql_keep_days)
        except:
            pass

        del maildir

        # Delete user object.
        try:
            # Delete object and its subtree.
            connUtils.delete_ldap_tree(dn=self.dnUser, conn=self.conn)

            if deleteFromGroups:
                self.deleteSingleUserFromGroups(self.mail)

            # Delete record from SQL database: real-time used quota.
            try:
                connUtils.deleteAccountFromUsedQuota([self.mail])
            except Exception as e:
                pass

            # Log delete action.
            web.logger(msg="Delete user: %s." % (self.mail),
                       domain=self.domain,
                       event='delete')
            return (True, )
        except ldap.LDAPError as e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 38
0
    def update(self, profile_type, mail, data):
        self.profile_type = web.safestr(profile_type)
        self.mail = web.safestr(mail)
        self.username, self.domain = self.mail.split('@', 1)

        if session.get('domainGlobalAdmin') is not True and session.get('username') != self.mail:
            # Don't allow to view/update other admins' profile.
            return (False, 'PERMISSION_DENIED')

        self.dn = ldaputils.convert_keyword_to_dn(self.mail, accountType='admin')
        if self.dn[0] is False:
            return self.dn

        mod_attrs = []
        if self.profile_type == 'general':
            # Get preferredLanguage.
            lang = web.safestr(data.get('preferredLanguage', 'en_US'))
            mod_attrs += [(ldap.MOD_REPLACE, 'preferredLanguage', lang)]

            # Get cn.
            cn = data.get('cn', None)
            mod_attrs += ldaputils.getSingleModAttr(attr='cn',
                                                    value=cn,
                                                    default=self.username)

            first_name = data.get('first_name', '')
            mod_attrs += ldaputils.getSingleModAttr(attr='givenName',
                                                    value=first_name,
                                                    default=self.username)

            last_name = data.get('last_name', '')
            mod_attrs += ldaputils.getSingleModAttr(attr='sn',
                                                    value=last_name,
                                                    default=self.username)

            # Get accountStatus.
            if 'accountStatus' in list(data.keys()):
                accountStatus = 'active'
            else:
                accountStatus = 'disabled'

            mod_attrs += [(ldap.MOD_REPLACE, 'accountStatus', accountStatus)]

            try:
                # Modify profiles.
                self.conn.modify_s(self.dn, mod_attrs)
                if session.get('username') == self.mail and \
                   session.get('lang', 'en_US') != lang:
                    session['lang'] = lang
            except ldap.LDAPError as e:
                return (False, ldaputils.getExceptionDesc(e))

        elif self.profile_type == 'password':
            self.cur_passwd = data.get('oldpw', None)
            self.newpw = web.safestr(data.get('newpw'))
            self.confirmpw = web.safestr(data.get('confirmpw'))

            result = iredutils.verify_new_password(self.newpw, self.confirmpw)
            if result[0] is True:
                self.passwd = result[1]
            else:
                return result

            # Change password.
            if self.cur_passwd is None and session.get('domainGlobalAdmin') is True:
                # Reset password without verify old password.
                self.cur_passwd = None
            else:
                self.cur_passwd = str(self.cur_passwd)

            connutils = connUtils.Utils()
            result = connutils.changePasswd(dn=self.dn, cur_passwd=self.cur_passwd, newpw=self.passwd,)
            if result[0] is True:
                return (True,)
            else:
                return result

        return (True,)
Esempio n. 39
0
class Login:
    def GET(self):
        if session.get('logged') is False:
            i = web.input(_unicode=False)

            # Show login page.
            return web.render('login.html',
                              languagemaps=languages.get_language_maps(),
                              webmaster=session.get('webmaster'),
                              msg=i.get('msg'))
        else:
            raise web.seeother('/dashboard')

    def POST(self):
        # Get username, password.
        i = web.input(_unicode=False)

        username = web.safestr(i.get('username', '').strip()).lower()
        password = i.get('password', '').strip()
        save_pass = web.safestr(i.get('save_pass', 'no').strip())

        if not iredutils.is_email(username):
            raise web.seeother('/login?msg=INVALID_USERNAME')

        if not password:
            raise web.seeother('/login?msg=EMPTY_PASSWORD')

        # Get LDAP URI.
        uri = settings.ldap_uri

        # Verify bind_dn & bind_pw.
        try:
            # Detect STARTTLS support.
            if uri.startswith('ldaps://'):
                starttls = True
            else:
                starttls = False

            # Set necessary option for STARTTLS.
            if starttls:
                ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)

            # Initialize connection.
            conn = ldap.initialize(uri)

            # Set LDAP protocol version: LDAP v3.
            conn.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)

            if starttls:
                conn.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)

            # synchronous bind.
            conn.bind_s(settings.ldap_bind_dn, settings.ldap_bind_password)
            conn.unbind_s()
        except (ldap.INVALID_CREDENTIALS):
            raise web.seeother('/login?msg=vmailadmin_INVALID_CREDENTIALS')
        except Exception, e:
            raise web.seeother('/login?msg=%s' % web.safestr(e))

        # Check whether it's a mail user
        dn_user = ldaputils.convert_keyword_to_dn(username, accountType='user')
        qr_user_auth = auth.Auth(uri=uri, dn=dn_user, password=password)

        qr_admin_auth = (False, 'INVALID_CREDENTIALS')
        if not qr_user_auth[0]:
            # Verify admin account under 'o=domainAdmins'.
            dn_admin = ldaputils.convert_keyword_to_dn(username, accountType='admin')
            qr_admin_auth = auth.Auth(uri=uri, dn=dn_admin, password=password)

            if not qr_admin_auth[0]:
                session['failed_times'] += 1
                web.logger(msg="Login failed.", admin=username, event='login', loglevel='error')
                raise web.seeother('/login?msg=INVALID_CREDENTIALS')

        if qr_admin_auth[0] or qr_user_auth[0]:
            session['username'] = username
            session['logged'] = True

            # Read preferred language from LDAP
            if qr_admin_auth[0] is True:
                adminLib = adminlib.Admin()
                adminProfile = adminLib.profile(username, attributes=['preferredLanguage'])
                if adminProfile[0] is True:
                    dn, entry = adminProfile[1][0]
                    lang = entry.get('preferredLanguage', [settings.default_language])[0]
                    session['lang'] = lang

            if qr_user_auth[0] is True:
                session['isMailUser'] = True

            web.config.session_parameters['cookie_name'] = 'iRedAdmin-Pro'
            # Session expire when client ip was changed.
            web.config.session_parameters['ignore_change_ip'] = False
            # Don't ignore session expiration.
            web.config.session_parameters['ignore_expiry'] = False

            if save_pass == 'yes':
                # Session timeout (in seconds).
                web.config.session_parameters['timeout'] = 86400    # 24 hours
            else:
                # Expire session when browser closed.
                web.config.session_parameters['timeout'] = 600      # 10 minutes

            web.logger(msg="Login success", event='login',)

            # Save selected language
            selected_language = str(i.get('lang', '')).strip()
            if selected_language != web.ctx.lang and \
               selected_language in languages.get_language_maps():
                session['lang'] = selected_language

            raise web.seeother('/dashboard/checknew')
        else:
            session['failed_times'] += 1
            web.logger(msg="Login failed.", admin=username, event='login', loglevel='error',)
            raise web.seeother('/login?msg=%s' % qr_admin_auth[1])
Esempio n. 40
0
    def add(self, domain, data):
        # Get domain name, username, cn.
        self.domain = web.safestr(data.get('domainName')).strip().lower()
        self.username = web.safestr(data.get('username')).strip().lower()
        self.mail = self.username + '@' + self.domain
        self.groups = data.get('groups', [])

        if not iredutils.is_domain(self.domain) or not iredutils.is_email(
                self.mail):
            return (False, 'MISSING_DOMAIN_OR_USERNAME')

        # Check account existing.
        connutils = connUtils.Utils()
        if connutils.isAccountExists(
                domain=self.domain,
                mail=self.mail,
        ):
            return (False, 'ALREADY_EXISTS')

        # Get @domainAccountSetting.
        domainLib = domainlib.Domain()
        result_domain_profile = domainLib.profile(domain=self.domain)

        # Initial parameters.
        domainAccountSetting = {}
        self.aliasDomains = []

        if result_domain_profile[0] is not True:
            return (False, result_domain_profile[1])

        domainProfile = result_domain_profile[1]
        domainAccountSetting = ldaputils.getAccountSettingFromLdapQueryResult(
            domainProfile, key='domainName').get(self.domain, {})
        self.aliasDomains = domainProfile[0][1].get('domainAliasName', [])

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

        # Check password.
        self.newpw = web.safestr(data.get('newpw'))
        self.confirmpw = web.safestr(data.get('confirmpw'))

        result = iredutils.verify_new_password(
            self.newpw,
            self.confirmpw,
            min_passwd_length=domainAccountSetting.get('minPasswordLength',
                                                       '0'),
            max_passwd_length=domainAccountSetting.get('maxPasswordLength',
                                                       '0'),
        )
        if result[0] is True:
            if 'storePasswordInPlainText' in data and settings.STORE_PASSWORD_IN_PLAIN_TEXT:
                self.passwd = iredutils.generate_password_hash(
                    result[1], pwscheme='PLAIN')
            else:
                self.passwd = iredutils.generate_password_hash(result[1])
        else:
            return result

        # Get display name.
        self.cn = data.get('cn')

        # Get user quota. Unit is MB.
        # 0 or empty is not allowed if domain quota is set, set to
        # @defaultUserQuota or @domainSpareQuotaSize

        # Initial final mailbox quota.
        self.quota = 0

        # Get mail quota from web form.
        defaultUserQuota = domainLib.getDomainDefaultUserQuota(
            self.domain, domainAccountSetting)
        self.mailQuota = str(data.get('mailQuota')).strip()
        if self.mailQuota.isdigit():
            self.mailQuota = int(self.mailQuota)
        else:
            self.mailQuota = defaultUserQuota

        # 0 means unlimited.
        domainQuotaSize, domainQuotaUnit = domainAccountSetting.get(
            'domainQuota', '0:GB').split(':')
        if int(domainQuotaSize) == 0:
            # Unlimited.
            self.quota = self.mailQuota
        else:
            # Get domain quota, convert to MB.
            if domainQuotaUnit == 'TB':
                domainQuota = int(domainQuotaSize) * 1024 * 1024  # TB
            elif domainQuotaUnit == 'GB':
                domainQuota = int(domainQuotaSize) * 1024  # GB
            else:
                domainQuota = int(domainQuotaSize)  # MB

            result = connutils.getDomainCurrentQuotaSizeFromLDAP(
                domain=self.domain)
            if result[0] is True:
                domainCurrentQuotaSize = result[1]
            else:
                domainCurrentQuotaSize = 0

            # Spare quota.
            domainSpareQuotaSize = domainQuota - domainCurrentQuotaSize / (
                1024 * 1024)

            if domainSpareQuotaSize <= 0:
                return (False, 'EXCEEDED_DOMAIN_QUOTA_SIZE')

            # Get FINAL mailbox quota.
            if self.mailQuota == 0:
                self.quota = domainSpareQuotaSize
            else:
                if domainSpareQuotaSize > self.mailQuota:
                    self.quota = self.mailQuota
                else:
                    self.quota = domainSpareQuotaSize

        # Get default groups.
        self.groups = [
            web.safestr(v)
            for v in domainAccountSetting.get('defaultList', '').split(',')
            if iredutils.is_email(v)
        ]

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

        # Get default mail lists which set in domain accountSetting.
        ldif = iredldif.ldif_mailuser(
            domain=self.domain,
            aliasDomains=self.aliasDomains,
            username=self.username,
            cn=self.cn,
            passwd=self.passwd,
            quota=self.quota,
            groups=self.groups,
            storageBaseDirectory=self.defaultStorageBaseDirectory,
        )

        domain_dn = ldaputils.convert_keyword_to_dn(self.domain,
                                                    accountType='domain')
        if domain_dn[0] is False:
            return domain_dn

        if attrs.RDN_USER == 'mail':
            self.dn = ldaputils.convert_keyword_to_dn(self.mail,
                                                      accountType='user')
            if self.dn[0] is False:
                return self.dn

        elif attrs.RDN_USER == 'cn':
            self.dn = 'cn=' + self.cn + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn
        elif attrs.RDN_USER == 'uid':
            self.dn = 'uid=' + self.username + ',' + attrs.DN_BETWEEN_USER_AND_DOMAIN + domain_dn
        else:
            return (False, 'UNSUPPORTED_USER_RDN')

        try:
            self.conn.add_s(
                ldap.filter.escape_filter_chars(self.dn),
                ldif,
            )
            web.logger(
                msg="Create user: %s." % (self.mail),
                domain=self.domain,
                event='create',
            )
            return (True, )
        except ldap.ALREADY_EXISTS:
            return (False, 'ALREADY_EXISTS')
        except Exception, e:
            return (False, ldaputils.getExceptionDesc(e))
Esempio n. 41
0
    def getSizelimitFromAccountLists(self, accountList, sizelimit=50, curPage=1, domain=None, accountType=None,):
        # Return a dict which contains:
        #   - totalAccounts: number of total accounts
        #   - accountList: list of accounts used to display in current page
        #   - totalPages: number of total pages show be showed in account list page.
        #   - totalQuota: number of domain quota size. Only available when accountType=='user'.

        # Initial a dict to set default values.
        result = {
            'totalAccounts': 0,         # Integer
            'accountList': [],          # List
            'totalPages': 0,            # Integer
            'totalQuota': 0,            # Integer
            'currentQuota': {},     # Dict
        }

        # Get total accounts.
        totalAccounts = len(accountList)
        result['totalAccounts'] = totalAccounts

        # Get number of actual pages.
        if totalAccounts % sizelimit == 0:
            totalPages = totalAccounts / sizelimit
        else:
            totalPages = (totalAccounts / sizelimit) + 1
        result['totalPages'] = totalPages

        if curPage >= totalPages:
            curPage = totalPages

        # Sort accounts in place.
        if isinstance(accountList, list):
            accountList.sort()
        else:
            pass

        # Get total domain mailbox quota.
        if accountType == 'user':
            counter = 0
            for i in accountList:
                quota = i[1].get('mailQuota', ['0'])[0]
                if quota.isdigit():
                    result['totalQuota'] += int(quota)
                    counter += 1

            # Update number of current domain quota size in LDAP (@attrs.ATTR_DOMAIN_CURRENT_QUOTA_SIZE).
            if domain is not None:
                # Update number of current domain quota size in LDAP.
                try:
                    dnDomain = ldaputils.convert_keyword_to_dn(domain, accountType='domain')
                    self.updateAttrSingleValue(
                        dn=dnDomain,
                        attr=attrs.ATTR_DOMAIN_CURRENT_QUOTA_SIZE,
                        value=str(result['totalQuota']),
                    )
                except:
                    pass

        # Get account list used to display in current page.
        if totalAccounts > sizelimit and totalAccounts < (curPage - 1) * sizelimit:
            accountList = accountList[-1:-sizelimit]
        else:
            accountList = accountList[(curPage - 1) * sizelimit: (curPage - 1) * sizelimit + sizelimit]
        result['accountList'] = accountList

        return result