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);
}
}
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);
}
}
Aggregations