Search in sources :

Example 16 with LdapEntry

use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.

the class LdapProvisioning method modifySignature.

@Override
public void modifySignature(Account account, String signatureId, Map<String, Object> signatureAttrs) throws ServiceException {
    removeAttrIgnoreCase("objectclass", signatureAttrs);
    validateSignatureAttrs(signatureAttrs);
    LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
    if (ldapEntry == null)
        throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
    String newName = (String) signatureAttrs.get(A_zimbraSignatureName);
    if (newName != null) {
        newName = newName.trim();
        // do not allow name to be wiped
        if (newName.length() == 0)
            throw ServiceException.INVALID_REQUEST("empty signature name is not allowed", null);
        // check for duplicate names
        List<Signature> sigs = getAllSignatures(account);
        for (Signature sig : sigs) {
            if (sig.getName().equalsIgnoreCase(newName) && !sig.getId().equals(signatureId))
                throw AccountServiceException.SIGNATURE_EXISTS(newName);
        }
    }
    // clear cache
    account.setCachedData(SIGNATURE_LIST_CACHE_KEY, null);
    if (LdapSignature.isAccountSignature(account, signatureId)) {
        LdapSignature.modifyAccountSignature(this, account, signatureAttrs);
    } else {
        LdapSignature signature = (LdapSignature) getSignatureById(account, ldapEntry, signatureId, null);
        if (signature == null)
            throw AccountServiceException.NO_SUCH_SIGNATURE(signatureId);
        boolean nameChanged = (newName != null && !newName.equals(signature.getName()));
        if (nameChanged)
            signatureAttrs.remove(A_zimbraSignatureName);
        modifyAttrs(signature, signatureAttrs, true);
        if (nameChanged) {
            // the signature cache could've been loaded again if getAllSignatures
            // were called in pre/poseModify callback, so we clear it again
            account.setCachedData(SIGNATURE_LIST_CACHE_KEY, null);
            renameSignature(ldapEntry, signature, newName);
        }
    }
}
Also used : LdapSignature(com.zimbra.cs.account.ldap.entry.LdapSignature) Signature(com.zimbra.cs.account.Signature) LdapSignature(com.zimbra.cs.account.ldap.entry.LdapSignature) LdapEntry(com.zimbra.cs.account.ldap.entry.LdapEntry)

Example 17 with LdapEntry

use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.

the class LdapProvisioning method getAllSignatures.

@Override
public List<Signature> getAllSignatures(Account account) throws ServiceException {
    LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
    if (ldapEntry == null)
        throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
    @SuppressWarnings("unchecked") List<Signature> result = (List<Signature>) account.getCachedData(SIGNATURE_LIST_CACHE_KEY);
    if (result != null) {
        return result;
    }
    result = new ArrayList<Signature>();
    Signature acctSig = LdapSignature.getAccountSignature(this, account);
    if (acctSig != null)
        result.add(acctSig);
    result = getSignaturesByQuery(account, ldapEntry, filterFactory.allSignatures(), null, result);
    result = Collections.unmodifiableList(result);
    account.setCachedData(SIGNATURE_LIST_CACHE_KEY, result);
    return result;
}
Also used : Signature(com.zimbra.cs.account.Signature) LdapSignature(com.zimbra.cs.account.ldap.entry.LdapSignature) LdapEntry(com.zimbra.cs.account.ldap.entry.LdapEntry) LdapDistributionList(com.zimbra.cs.account.ldap.entry.LdapDistributionList) ArrayList(java.util.ArrayList) List(java.util.List) DistributionList(com.zimbra.cs.account.DistributionList)

Example 18 with LdapEntry

use of com.zimbra.cs.account.ldap.entry.LdapEntry 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 19 with LdapEntry

use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.

the class LdapProvisioning method createSignature.

private Signature createSignature(Account account, String signatureName, Map<String, Object> signatureAttrs, boolean restoring) throws ServiceException {
    signatureName = signatureName.trim();
    removeAttrIgnoreCase("objectclass", signatureAttrs);
    validateSignatureAttrs(signatureAttrs);
    LdapEntry ldapEntry = (LdapEntry) (account instanceof LdapEntry ? account : getAccountById(account.getId()));
    if (ldapEntry == null)
        throw AccountServiceException.NO_SUCH_ACCOUNT(account.getName());
    /*
         * check if the signature name already exists
         *
         * We check if the signatureName is the same as the signature on the account.
         * For signatures that are in the signature LDAP entries, JNDI will throw
         * NameAlreadyBoundException for duplicate names.
         *
         */
    Signature acctSig = LdapSignature.getAccountSignature(this, account);
    if (acctSig != null && signatureName.equalsIgnoreCase(acctSig.getName()))
        throw AccountServiceException.SIGNATURE_EXISTS(signatureName);
    boolean setAsDefault = false;
    List<Signature> existing = getAllSignatures(account);
    // If the signature id is supplied with the request, check that it
    // is not associated with an existing signature
    String signatureId = (String) signatureAttrs.get(Provisioning.A_zimbraSignatureId);
    if (signatureId != null) {
        for (Signature signature : existing) {
            if (signatureId.equals(signature.getAttr(Provisioning.A_zimbraSignatureId))) {
                throw AccountServiceException.SIGNATURE_EXISTS(signatureId);
            }
        }
    }
    int numSigs = existing.size();
    if (numSigs >= account.getLongAttr(A_zimbraSignatureMaxNumEntries, 20))
        throw AccountServiceException.TOO_MANY_SIGNATURES();
    else if (numSigs == 0)
        setAsDefault = true;
    account.setCachedData(SIGNATURE_LIST_CACHE_KEY, null);
    boolean checkImmutable = !restoring;
    CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
    callbackContext.setData(DataKey.MAX_SIGNATURE_LEN, String.valueOf(account.getMailSignatureMaxLength()));
    AttributeManager.getInstance().preModify(signatureAttrs, null, callbackContext, checkImmutable);
    if (signatureId == null) {
        signatureId = LdapUtil.generateUUID();
        signatureAttrs.put(Provisioning.A_zimbraSignatureId, signatureId);
    }
    if (acctSig == null) {
        // the slot on the account is not occupied, use it
        signatureAttrs.put(Provisioning.A_zimbraSignatureName, signatureName);
        // pass in setAsDefault as an optimization, since we are updating the account
        // entry, we can update the default attr in one LDAP write
        LdapSignature.createAccountSignature(this, account, signatureAttrs, setAsDefault);
        return LdapSignature.getAccountSignature(this, account);
    }
    ZLdapContext zlc = null;
    try {
        zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_SIGNATURE);
        String dn = getSignatureDn(ldapEntry, signatureName);
        ZMutableEntry entry = LdapClient.createMutableEntry();
        entry.mapToAttrs(signatureAttrs);
        entry.setAttr(A_objectClass, "zimbraSignature");
        entry.setAttr(Provisioning.A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()));
        entry.setDN(dn);
        zlc.createEntry(entry);
        Signature signature = getSignatureById(account, ldapEntry, signatureId, zlc);
        AttributeManager.getInstance().postModify(signatureAttrs, signature, callbackContext);
        if (setAsDefault)
            setDefaultSignature(account, signatureId);
        return signature;
    } catch (LdapEntryAlreadyExistException nabe) {
        throw AccountServiceException.SIGNATURE_EXISTS(signatureName);
    } catch (LdapException e) {
        throw e;
    } catch (AccountServiceException e) {
        throw e;
    } catch (ServiceException e) {
        throw ServiceException.FAILURE("unable to create signature: " + signatureName, e);
    } finally {
        LdapClient.closeContext(zlc);
    }
}
Also used : ZMutableEntry(com.zimbra.cs.ldap.ZMutableEntry) LdapEntryAlreadyExistException(com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) LdapEntry(com.zimbra.cs.account.ldap.entry.LdapEntry) Date(java.util.Date) 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) Signature(com.zimbra.cs.account.Signature) LdapSignature(com.zimbra.cs.account.ldap.entry.LdapSignature) CallbackContext(com.zimbra.cs.account.callback.CallbackContext) LdapException(com.zimbra.cs.ldap.LdapException)

Example 20 with LdapEntry

use of com.zimbra.cs.account.ldap.entry.LdapEntry in project zm-mailbox by Zimbra.

the class TestProvAlias method testRemoveAlias_entryExist_aliasExist_aliasPointToOtherEntry.

//
// A - alias points to other existing entry
//
@Test
public void testRemoveAlias_entryExist_aliasExist_aliasPointToOtherEntry() throws Exception {
    String testName = getTestName();
    // create the domain
    String domainName = "EE-AE-aliasPointToOtherEntry" + "." + BASE_DOMAIN_NAME;
    domainName = domainName.toLowerCase();
    Map<String, Object> attrs = new HashMap<String, Object>();
    attrs.put(Provisioning.A_zimbraDomainType, Provisioning.DomainType.local.name());
    Domain domain = prov.createDomain(domainName, attrs);
    // create the account the alias points to
    String acctName = getEmail("acct-1", domainName);
    Account acct = prov.createAccount(acctName, PASSWORD, new HashMap<String, Object>());
    // add an alias to the account
    String aliasName = getEmail("alias-1", domainName);
    prov.addAlias(acct, aliasName);
    // create 2 DLs
    String dl1Name = getEmail("dl-1", domainName);
    DistributionList dl1 = prov.createDistributionList(dl1Name, new HashMap<String, Object>());
    String dl2Name = getEmail("dl-2", domainName);
    DistributionList dl2 = prov.createDistributionList(dl2Name, new HashMap<String, Object>());
    // add the alias to the two DLs
    prov.addMembers(dl1, new String[] { aliasName });
    prov.addMembers(dl2, new String[] { aliasName });
    // create another account
    String otherAcctName = getEmail("acct-other", domainName);
    Account otherAcct = prov.createAccount(otherAcctName, PASSWORD, new HashMap<String, Object>());
    // and hack the other account to also contain the alias in it's mail/zimbraMailAlias attrs
    // the hacked attrs should be removed after the removeAlais call
    {
        Map<String, Object> attributes = new HashMap<String, Object>();
        // can no long do this, we now have an unique constraint on mail
        // attributes.put(Provisioning.A_mail, aliasName);
        attributes.put(Provisioning.A_zimbraMailAlias, aliasName);
        LdapEntry ldapAccount = (LdapEntry) otherAcct;
        ((LdapProv) prov).getHelper().modifyEntry(ldapAccount.getDN(), attributes, (Entry) ldapAccount, LdapUsage.UNITTEST);
        // make sure the attrs did get hacked in
        prov.reload(otherAcct);
        Set<String> values;
        // values = otherAcct.getMultiAttrSet(Provisioning.A_mail);
        // assertTrue(values.contains(aliasName));
        values = otherAcct.getMultiAttrSet(Provisioning.A_zimbraMailAlias);
        assertTrue(values.contains(aliasName));
    }
    // remove the alias, on the "other" account, which is *not* the target for the alias we are removing
    // ensure we *do* get a NO_SUCH_ALIAS exception
    boolean good = false;
    try {
        prov.removeAlias(otherAcct, aliasName);
    } catch (ServiceException e) {
        assertEquals(e.getCode(), (AccountServiceException.NO_SUCH_ALIAS));
        good = true;
    }
    assertTrue(good);
    // reload all entries
    prov.reload(acct);
    prov.reload(otherAcct);
    prov.reload(dl1);
    prov.reload(dl2);
    Set<String> values;
    // ensure the alias is still on the account
    values = acct.getMultiAttrSet(Provisioning.A_mail);
    assertTrue(values.contains(aliasName));
    values = acct.getMultiAttrSet(Provisioning.A_zimbraMailAlias);
    assertTrue(values.contains(aliasName));
    // ensure the hacked in attrs are removed from the other account
    values = otherAcct.getMultiAttrSet(Provisioning.A_mail);
    assertFalse(values.contains(aliasName));
    values = otherAcct.getMultiAttrSet(Provisioning.A_zimbraMailAlias);
    assertFalse(values.contains(aliasName));
    // ensure the alias is *not* removed from any the DLs
    values = dl1.getMultiAttrSet(Provisioning.A_zimbraMailForwardingAddress);
    assertTrue(values.contains(aliasName));
    values = dl2.getMultiAttrSet(Provisioning.A_zimbraMailForwardingAddress);
    assertTrue(values.contains(aliasName));
    // ensure the alias entry is *not* removed
    List<NamedEntry> aliases = searchAliasesInDomain(domain);
    assertEquals(aliases.size(), 1);
    assertTrue(aliases.get(0).getName().equals(aliasName));
}
Also used : Account(com.zimbra.cs.account.Account) Set(java.util.Set) HashMap(java.util.HashMap) LdapEntry(com.zimbra.cs.account.ldap.entry.LdapEntry) LdapProv(com.zimbra.cs.account.ldap.LdapProv) NamedEntry(com.zimbra.cs.account.NamedEntry) NamedEntry(com.zimbra.cs.account.NamedEntry) CacheEntry(com.zimbra.cs.account.Provisioning.CacheEntry) Entry(com.zimbra.cs.account.Entry) LdapEntry(com.zimbra.cs.account.ldap.entry.LdapEntry) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ServiceException(com.zimbra.common.service.ServiceException) Domain(com.zimbra.cs.account.Domain) HashMap(java.util.HashMap) Map(java.util.Map) DistributionList(com.zimbra.cs.account.DistributionList)

Aggregations

LdapEntry (com.zimbra.cs.account.ldap.entry.LdapEntry)22 ServiceException (com.zimbra.common.service.ServiceException)15 AccountServiceException (com.zimbra.cs.account.AccountServiceException)15 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)12 Account (com.zimbra.cs.account.Account)10 ZLdapContext (com.zimbra.cs.ldap.ZLdapContext)10 DistributionList (com.zimbra.cs.account.DistributionList)9 Domain (com.zimbra.cs.account.Domain)9 HashMap (java.util.HashMap)9 NamedEntry (com.zimbra.cs.account.NamedEntry)7 List (java.util.List)7 LdapProv (com.zimbra.cs.account.ldap.LdapProv)6 LdapException (com.zimbra.cs.ldap.LdapException)5 LdapEntryAlreadyExistException (com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException)5 GuestAccount (com.zimbra.cs.account.GuestAccount)4 Signature (com.zimbra.cs.account.Signature)4 LdapAccount (com.zimbra.cs.account.ldap.entry.LdapAccount)4 LdapDataSource (com.zimbra.cs.account.ldap.entry.LdapDataSource)4 LdapIdentity (com.zimbra.cs.account.ldap.entry.LdapIdentity)4 LdapSignature (com.zimbra.cs.account.ldap.entry.LdapSignature)4