Search in sources :

Example 1 with LdapUsage

use of com.zimbra.cs.ldap.LdapUsage in project zm-mailbox by Zimbra.

the class LdapProvisioning method addAliasInternal.

private void addAliasInternal(NamedEntry entry, String alias) throws ServiceException {
    LdapUsage ldapUsage = null;
    String targetDomainName = null;
    AliasedEntry aliasedEntry = null;
    if (entry instanceof Account) {
        aliasedEntry = (AliasedEntry) entry;
        targetDomainName = ((Account) entry).getDomainName();
        ldapUsage = LdapUsage.ADD_ALIAS_ACCOUNT;
    } else if (entry instanceof Group) {
        aliasedEntry = (AliasedEntry) entry;
        ldapUsage = LdapUsage.ADD_ALIAS_DL;
        targetDomainName = ((Group) entry).getDomainName();
    } else {
        throw ServiceException.FAILURE("invalid entry type for alias", null);
    }
    alias = alias.toLowerCase().trim();
    alias = IDNUtil.toAsciiEmail(alias);
    validEmailAddress(alias);
    String[] parts = alias.split("@");
    String aliasName = parts[0];
    String aliasDomain = parts[1];
    ZLdapContext zlc = null;
    String aliasDn = null;
    try {
        zlc = LdapClient.getContext(LdapServerType.MASTER, ldapUsage);
        Domain domain = getDomainByAsciiName(aliasDomain, zlc);
        if (domain == null)
            throw AccountServiceException.NO_SUCH_DOMAIN(aliasDomain);
        aliasDn = mDIT.aliasDN(((LdapEntry) entry).getDN(), targetDomainName, aliasName, aliasDomain);
        // the create and addAttr ideally would be in the same transaction
        String aliasUuid = LdapUtil.generateUUID();
        String targetEntryId = entry.getId();
        try {
            zlc.createEntry(aliasDn, "zimbraAlias", new String[] { Provisioning.A_uid, aliasName, Provisioning.A_zimbraId, aliasUuid, Provisioning.A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()), Provisioning.A_zimbraAliasTargetId, targetEntryId });
        } catch (LdapEntryAlreadyExistException e) {
            /*
                 * check if the alias is a dangling alias.  If so remove the dangling alias
                 * and create a new one.
                 */
            ZAttributes attrs = helper.getAttributes(zlc, aliasDn);
            // see if the entry is an alias
            if (!isEntryAlias(attrs))
                throw e;
            Alias aliasEntry = makeAlias(aliasDn, attrs);
            NamedEntry targetEntry = searchAliasTarget(aliasEntry, false);
            if (targetEntry == null) {
                // remove the dangling alias
                try {
                    removeAliasInternal(null, alias);
                } catch (ServiceException se) {
                // ignore
                }
                // try creating the alias again
                zlc.createEntry(aliasDn, "zimbraAlias", new String[] { Provisioning.A_uid, aliasName, Provisioning.A_zimbraId, aliasUuid, Provisioning.A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()), Provisioning.A_zimbraAliasTargetId, targetEntryId });
            } else if (targetEntryId.equals(targetEntry.getId())) {
                // the alias target points to this account/DL
                Set<String> mailAliases = entry.getMultiAttrSet(Provisioning.A_zimbraMailAlias);
                Set<String> mails = entry.getMultiAttrSet(Provisioning.A_mail);
                if (mailAliases != null && mailAliases.contains(alias) && mails != null && mails.contains(alias)) {
                    throw e;
                } else {
                    ZimbraLog.account.warn("alias entry exists at " + aliasDn + ", but either mail or zimbraMailAlias of the target does not contain " + alias + ", adding " + alias + " to entry " + entry.getName());
                }
            } else {
                // for which the alias is being added for, rethrow the naming exception
                throw e;
            }
        }
        HashMap<String, String> attrs = new HashMap<String, String>();
        attrs.put("+" + Provisioning.A_zimbraMailAlias, alias);
        attrs.put("+" + Provisioning.A_mail, alias);
        // UGH
        modifyAttrsInternal(entry, zlc, attrs);
        removeExternalAddrsFromAllDynamicGroups(aliasedEntry.getAllAddrsSet(), zlc);
    } catch (LdapEntryAlreadyExistException nabe) {
        throw AccountServiceException.ACCOUNT_EXISTS(alias, aliasDn, nabe);
    } catch (LdapException e) {
        throw e;
    } catch (AccountServiceException e) {
        throw e;
    } catch (ServiceException e) {
        throw ServiceException.FAILURE("unable to create alias: " + e.getMessage(), e);
    } finally {
        LdapClient.closeContext(zlc);
    }
}
Also used : Account(com.zimbra.cs.account.Account) GuestAccount(com.zimbra.cs.account.GuestAccount) LdapAccount(com.zimbra.cs.account.ldap.entry.LdapAccount) Group(com.zimbra.cs.account.Group) DynamicGroup(com.zimbra.cs.account.DynamicGroup) LdapDynamicGroup(com.zimbra.cs.account.ldap.entry.LdapDynamicGroup) LdapEntryAlreadyExistException(com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) HashMap(java.util.HashMap) AliasedEntry(com.zimbra.cs.account.AliasedEntry) LdapEntry(com.zimbra.cs.account.ldap.entry.LdapEntry) Date(java.util.Date) NamedEntry(com.zimbra.cs.account.NamedEntry) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) LdapAlias(com.zimbra.cs.account.ldap.entry.LdapAlias) Alias(com.zimbra.cs.account.Alias) ZAttributes(com.zimbra.cs.ldap.ZAttributes) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain) LdapException(com.zimbra.cs.ldap.LdapException) LdapUsage(com.zimbra.cs.ldap.LdapUsage)

Example 2 with LdapUsage

use of com.zimbra.cs.ldap.LdapUsage in project zm-mailbox by Zimbra.

the class LdapProvisioning method removeAliasInternal.

/*
     * 1. remove alias from mail and zimbraMailAlias attributes of the entry
     * 2. remove alias from all distribution lists
     * 3. delete the alias entry
     *
     * A. entry exists, alias exists
     *    - if alias points to the entry:            do 1, 2, 3
     *    - if alias points to other existing entry: do 1, and then throw NO_SUCH_ALIAS
     *    - if alias points to a non-existing entry: do 1, 2, 3, and then throw NO_SUCH_ALIAS
     *
     * B. entry exists, alias does not exist:  do 1, 2, and then throw NO_SUCH_ALIAS
     *
     * C. entry does not exist, alias exists:
     *    - if alias points to other existing entry: do nothing (and then throw NO_SUCH_ACCOUNT/NO_SUCH_DISTRIBUTION_LIST in ProvUtil)
     *    - if alias points to a non-existing entry: do 2, 3 (and then throw NO_SUCH_ACCOUNT/NO_SUCH_DISTRIBUTION_LIST in ProvUtil)
     *
     * D. entry does not exist, alias does not exist:  do 2 (and then throw NO_SUCH_ACCOUNT/NO_SUCH_DISTRIBUTION_LIST in ProvUtil)
     *
     *
     */
private void removeAliasInternal(NamedEntry entry, String alias) throws ServiceException {
    LdapUsage ldapUsage = null;
    if (entry instanceof Account) {
        ldapUsage = LdapUsage.REMOVE_ALIAS_ACCOUNT;
    } else if (entry instanceof Group) {
        ldapUsage = LdapUsage.REMOVE_ALIAS_DL;
    } else {
        ldapUsage = LdapUsage.REMOVE_ALIAS;
    }
    ZLdapContext zlc = null;
    try {
        zlc = LdapClient.getContext(LdapServerType.MASTER, ldapUsage);
        alias = alias.toLowerCase();
        alias = IDNUtil.toAsciiEmail(alias);
        String[] parts = alias.split("@");
        String aliasName = parts[0];
        String aliasDomain = parts[1];
        Domain domain = getDomainByAsciiName(aliasDomain, zlc);
        if (domain == null)
            throw AccountServiceException.NO_SUCH_DOMAIN(aliasDomain);
        String targetDn = (entry == null) ? null : ((LdapEntry) entry).getDN();
        String targetDomainName = null;
        if (entry != null) {
            if (entry instanceof Account) {
                targetDomainName = ((Account) entry).getDomainName();
            } else if (entry instanceof Group) {
                targetDomainName = ((Group) entry).getDomainName();
            } else {
                throw ServiceException.INVALID_REQUEST("invalid entry type for alias", null);
            }
        }
        String aliasDn = mDIT.aliasDN(targetDn, targetDomainName, aliasName, aliasDomain);
        ZAttributes aliasAttrs = null;
        Alias aliasEntry = null;
        try {
            aliasAttrs = helper.getAttributes(zlc, aliasDn);
            // see if the entry is an alias
            if (!isEntryAlias(aliasAttrs))
                throw AccountServiceException.NO_SUCH_ALIAS(alias);
            aliasEntry = makeAlias(aliasDn, aliasAttrs);
        } catch (ServiceException e) {
            ZimbraLog.account.warn("alias " + alias + " does not exist");
        }
        NamedEntry targetEntry = null;
        if (aliasEntry != null)
            targetEntry = searchAliasTarget(aliasEntry, false);
        boolean aliasPointsToEntry = ((entry != null) && (aliasEntry != null) && entry.getId().equals(aliasEntry.getAttr(Provisioning.A_zimbraAliasTargetId)));
        boolean aliasPointsToOtherExistingEntry = ((aliasEntry != null) && (targetEntry != null) && ((entry == null) || (!entry.getId().equals(targetEntry.getId()))));
        boolean aliasPointsToNonExistingEntry = ((aliasEntry != null) && (targetEntry == null));
        // 1. remove alias from mail/zimbraMailAlias attrs
        if (entry != null) {
            try {
                HashMap<String, String> attrs = new HashMap<String, String>();
                attrs.put("-" + Provisioning.A_mail, alias);
                attrs.put("-" + Provisioning.A_zimbraMailAlias, alias);
                modifyAttrsInternal(entry, zlc, attrs);
            } catch (ServiceException e) {
                ZimbraLog.account.warn("unable to remove zimbraMailAlias/mail attrs: " + alias);
            }
        }
        // 2. remove address from all DLs
        if (!aliasPointsToOtherExistingEntry) {
            removeAddressFromAllDistributionLists(alias);
        }
        // 3. remove the alias entry
        if (aliasPointsToEntry || aliasPointsToNonExistingEntry) {
            try {
                zlc.deleteEntry(aliasDn);
            } catch (ServiceException e) {
                // should not happen, log it
                ZimbraLog.account.warn("unable to remove alias entry at : " + aliasDn);
            }
        }
        // throw NO_SUCH_ALIAS if necessary
        if (((entry != null) && (aliasEntry == null)) || ((entry != null) && (aliasEntry != null) && !aliasPointsToEntry))
            throw AccountServiceException.NO_SUCH_ALIAS(alias);
    } finally {
        LdapClient.closeContext(zlc);
    }
}
Also used : Account(com.zimbra.cs.account.Account) GuestAccount(com.zimbra.cs.account.GuestAccount) LdapAccount(com.zimbra.cs.account.ldap.entry.LdapAccount) Group(com.zimbra.cs.account.Group) DynamicGroup(com.zimbra.cs.account.DynamicGroup) LdapDynamicGroup(com.zimbra.cs.account.ldap.entry.LdapDynamicGroup) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) HashMap(java.util.HashMap) NamedEntry(com.zimbra.cs.account.NamedEntry) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) LdapAlias(com.zimbra.cs.account.ldap.entry.LdapAlias) Alias(com.zimbra.cs.account.Alias) ZAttributes(com.zimbra.cs.ldap.ZAttributes) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain) LdapUsage(com.zimbra.cs.ldap.LdapUsage)

Aggregations

ServiceException (com.zimbra.common.service.ServiceException)2 Account (com.zimbra.cs.account.Account)2 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)2 Alias (com.zimbra.cs.account.Alias)2 Domain (com.zimbra.cs.account.Domain)2 DynamicGroup (com.zimbra.cs.account.DynamicGroup)2 Group (com.zimbra.cs.account.Group)2 GuestAccount (com.zimbra.cs.account.GuestAccount)2 NamedEntry (com.zimbra.cs.account.NamedEntry)2 LdapAccount (com.zimbra.cs.account.ldap.entry.LdapAccount)2 LdapAlias (com.zimbra.cs.account.ldap.entry.LdapAlias)2 LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)2 LdapDynamicGroup (com.zimbra.cs.account.ldap.entry.LdapDynamicGroup)2 LdapUsage (com.zimbra.cs.ldap.LdapUsage)2 ZAttributes (com.zimbra.cs.ldap.ZAttributes)2 ZLdapContext (com.zimbra.cs.ldap.ZLdapContext)2 HashMap (java.util.HashMap)2 AliasedEntry (com.zimbra.cs.account.AliasedEntry)1 LdapEntry (com.zimbra.cs.account.ldap.entry.LdapEntry)1