use of com.zimbra.cs.account.ldap.entry.LdapDistributionList in project zm-mailbox by Zimbra.
the class LdapProvisioning method deleteDistributionList.
@Override
public void deleteDistributionList(String zimbraId) throws ServiceException {
LdapDistributionList dl = (LdapDistributionList) getDistributionListByIdInternal(zimbraId);
if (dl == null) {
throw AccountServiceException.NO_SUCH_DISTRIBUTION_LIST(zimbraId);
}
deleteDistributionList(dl);
}
use of com.zimbra.cs.account.ldap.entry.LdapDistributionList in project zm-mailbox by Zimbra.
the class LdapProvisioning method addDistributionListMembers.
private void addDistributionListMembers(DistributionList dl, String[] members) throws ServiceException {
Set<String> existing = dl.getMultiAttrSet(Provisioning.A_zimbraMailForwardingAddress);
Set<String> mods = new HashSet<String>();
// all addrs of this DL
AddrsOfEntry addrsOfDL = getAllAddressesOfEntry(dl.getName());
String dlOU = null;
if (dl.isHABGroup() && dl instanceof LdapDistributionList) {
dlOU = getGroupOU(((LdapDistributionList) dl).getDN());
}
for (int i = 0; i < members.length; i++) {
String memberName = members[i].toLowerCase();
memberName = IDNUtil.toAsciiEmail(memberName);
if (addrsOfDL.isIn(memberName))
throw ServiceException.INVALID_REQUEST("Cannot add self as a member: " + memberName, null);
if (dl.isHABGroup()) {
Group memberGroup = getGroup(Key.DistributionListBy.name, memberName);
if (memberGroup != null) {
if (!memberGroup.isHABGroup()) {
throw ServiceException.INVALID_REQUEST(String.format("Cannot add non-hab group: %s as a member in hab group ", memberName), null);
} else if (!isGroupInOU(memberGroup, dlOU)) {
throw ServiceException.INVALID_REQUEST(String.format("Cannot add group: %s as a member, since it belongs to different OU", memberName), null);
}
}
}
// cannot add a dynamic group as member in non-hab group
DynamicGroup dynMember = getDynamicGroup(Key.DistributionListBy.name, memberName, null, Boolean.FALSE);
if (dynMember != null) {
if (dl.isHABGroup()) {
if (dlIsInDynamicHABGroup(dynMember, addrsOfDL.getAll())) {
throw ServiceException.INVALID_REQUEST(String.format("Cannot add dynamic group: %s as a member, since it contains the parent", memberName), null);
}
} else {
throw ServiceException.INVALID_REQUEST("Cannot add dynamic group as a member: " + memberName, null);
}
}
if (!existing.contains(memberName)) {
mods.add(memberName);
// clear the DL cache on accounts/dl
// can't do prov.getFromCache because it only caches by primary name
Account acct = get(AccountBy.name, memberName);
if (acct != null) {
clearUpwardMembershipCache(acct);
} else {
// for DistributionList/ACLGroup, get it from cache because
// if the dl is not in cache, after loading it prov.getAclGroup
// always compute the upward membership. Sounds silly if we are
// about to clean the cache. If memberName is indeed an alias
// of one of the cached DL/ACLGroup, it will get expired after 15
// mins, just like the multi-node case.
//
// Note: do not call clearUpwardMembershipCache for AclGroup because
// the upward membership cache for that is computed and cache only when
// the entry is loaded/being cached, instead of lazily computed like we
// do for account.
removeGroupFromCache(Key.DistributionListBy.name, memberName);
}
}
}
if (mods.isEmpty()) {
// nothing to do...
return;
}
PermissionCache.invalidateCache();
cleanGroupMembersCache(dl);
Map<String, String[]> modmap = new HashMap<String, String[]>();
modmap.put("+" + Provisioning.A_zimbraMailForwardingAddress, mods.toArray(new String[0]));
modifyAttrs(dl, modmap, true);
}
use of com.zimbra.cs.account.ldap.entry.LdapDistributionList in project zm-mailbox by Zimbra.
the class LdapProvisioning method deleteDistributionList.
private void deleteDistributionList(LdapDistributionList dl, boolean cascadeDelete) throws ServiceException {
// check if cascadeDelete is true. If it's true, delete all subgroups.
if (dl.isHABGroup()) {
if (cascadeDelete) {
Set<String> members = dl.getAllMembersSet();
for (String member : members) {
LdapDistributionList subDl = (LdapDistributionList) getDistributionListByNameInternal(member);
if (subDl != null && subDl.isHABGroup()) {
deleteDistributionList(subDl, cascadeDelete);
} else {
DynamicGroup dg = getDynamicGroupBasic(DistributionListBy.name, member, LdapClient.getContext(LdapServerType.MASTER, LdapUsage.DELETE_DYNAMICGROUP));
if (dg != null && dg.isHABGroup()) {
deleteDynamicGroup((LdapDynamicGroup) dg);
}
}
}
} else {
if (dl.getAllMembers().length > 0) {
throw ServiceException.INVALID_REQUEST("Can not delete hab group when members are present in group.", null);
}
}
}
String zimbraId = dl.getId();
// make a copy of all addrs of this DL, after the delete all aliases on this dl
// object will be gone, but we need to remove them from the all groups cache after the DL is deleted
Set<String> addrs = new HashSet<String>(dl.getMultiAttrSet(Provisioning.A_mail));
// remove the DL from all DLs
// this doesn't throw any exceptions
removeAddressFromAllDistributionLists(dl.getName());
// delete all aliases of the DL
String[] aliases = dl.getAliases();
if (aliases != null) {
String dlName = dl.getName();
for (int i = 0; i < aliases.length; i++) {
// this "alias" if it is the primary name, the entire entry will be deleted anyway.
if (!dlName.equalsIgnoreCase(aliases[i])) {
// this also removes each alias from any DLs
removeAlias(dl, aliases[i]);
}
}
}
// delete all grants granted to the DL
try {
RightCommand.revokeAllRights(this, GranteeType.GT_GROUP, zimbraId);
} catch (ServiceException e) {
// eat the exception and continue
ZimbraLog.account.warn("cannot revoke grants", e);
}
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.DELETE_DISTRIBUTIONLIST);
zlc.deleteEntry(dl.getDN());
groupCache.remove(dl);
allDLs.removeGroup(addrs);
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to purge distribution list: " + zimbraId, e);
} finally {
LdapClient.closeContext(zlc);
}
PermissionCache.invalidateCache();
}
use of com.zimbra.cs.account.ldap.entry.LdapDistributionList in project zm-mailbox by Zimbra.
the class LdapProvisioning method renameDistributionList.
@Override
public void renameDistributionList(String zimbraId, String newEmail) throws ServiceException {
newEmail = IDNUtil.toAsciiEmail(newEmail);
validEmailAddress(newEmail);
boolean domainChanged = false;
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.RENAME_DISTRIBUTIONLIST);
LdapDistributionList dl = (LdapDistributionList) getDistributionListById(zimbraId, zlc);
if (dl == null) {
throw AccountServiceException.NO_SUCH_DISTRIBUTION_LIST(zimbraId);
}
groupCache.remove(dl);
String oldEmail = dl.getName();
String oldDomain = EmailUtil.getValidDomainPart(oldEmail);
newEmail = newEmail.toLowerCase().trim();
String[] parts = EmailUtil.getLocalPartAndDomain(newEmail);
if (parts == null)
throw ServiceException.INVALID_REQUEST("bad value for newName", null);
String newLocal = parts[0];
String newDomain = parts[1];
domainChanged = !oldDomain.equals(newDomain);
Domain domain = getDomainByAsciiName(newDomain, zlc);
if (domain == null) {
throw AccountServiceException.NO_SUCH_DOMAIN(newDomain);
}
if (domainChanged) {
// make sure the new domain is a local domain
if (!domain.isLocal()) {
throw ServiceException.INVALID_REQUEST("domain type must be local", null);
}
}
Map<String, Object> attrs = new HashMap<String, Object>();
ReplaceAddressResult replacedMails = replaceMailAddresses(dl, Provisioning.A_mail, oldEmail, newEmail);
if (replacedMails.newAddrs().length == 0) {
// Set mail to newName if the account currently does not have a mail
attrs.put(Provisioning.A_mail, newEmail);
} else {
attrs.put(Provisioning.A_mail, replacedMails.newAddrs());
}
ReplaceAddressResult replacedAliases = replaceMailAddresses(dl, Provisioning.A_zimbraMailAlias, oldEmail, newEmail);
if (replacedAliases.newAddrs().length > 0) {
attrs.put(Provisioning.A_zimbraMailAlias, replacedAliases.newAddrs());
String newDomainDN = mDIT.domainToAccountSearchDN(newDomain);
// check up front if any of renamed aliases already exists in the new domain (if domain also got changed)
if (domainChanged && addressExistsUnderDN(zlc, newDomainDN, replacedAliases.newAddrs())) {
throw AccountServiceException.DISTRIBUTION_LIST_EXISTS(newEmail);
}
}
ReplaceAddressResult replacedAllowAddrForDelegatedSender = replaceMailAddresses(dl, Provisioning.A_zimbraPrefAllowAddressForDelegatedSender, oldEmail, newEmail);
if (replacedAllowAddrForDelegatedSender.newAddrs().length > 0) {
attrs.put(Provisioning.A_zimbraPrefAllowAddressForDelegatedSender, replacedAllowAddrForDelegatedSender.newAddrs());
}
String oldDn = dl.getDN();
String newDn = mDIT.distributionListDNRename(oldDn, newLocal, domain.getName());
boolean dnChanged = (!oldDn.equals(newDn));
if (dnChanged) {
// uid will be changed during renameEntry, so no need to modify it
// OpenLDAP is OK modifying it, as long as it matches the new DN, but
// InMemoryDirectoryServer does not like it.
attrs.remove(A_uid);
} else {
/*
* always reset uid to the local part, because in non default DIT the naming RDN might not
* be uid, and ctxt.rename won't change the uid to the new localpart in that case.
*/
attrs.put(A_uid, newLocal);
}
// move over the distribution list entry
if (dnChanged) {
zlc.renameEntry(oldDn, newDn);
}
dl = (LdapDistributionList) getDistributionListById(zimbraId, zlc);
// rename the distribution list and all it's renamed aliases to the new name
// in all distribution lists.
// Doesn't throw exceptions, just logs.
renameAddressesInAllDistributionLists(oldEmail, newEmail, replacedAliases);
// doesn't throw exceptions, just logs
if (domainChanged) {
String newUid = dl.getAttr(Provisioning.A_uid);
moveAliases(zlc, replacedAliases, newDomain, newUid, oldDn, newDn, oldDomain, newDomain);
}
// could fail. So catch service exception here and log error
try {
modifyAttrsInternal(dl, zlc, attrs);
} catch (ServiceException e) {
ZimbraLog.account.error("distribution list renamed to " + newLocal + " but failed to move old name's LDAP attributes", e);
throw e;
}
removeExternalAddrsFromAllDynamicGroups(dl.getAllAddrsSet(), zlc);
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.DISTRIBUTION_LIST_EXISTS(newEmail);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to rename distribution list: " + zimbraId, e);
} finally {
LdapClient.closeContext(zlc);
}
if (domainChanged) {
PermissionCache.invalidateCache();
}
}
use of com.zimbra.cs.account.ldap.entry.LdapDistributionList in project zm-mailbox by Zimbra.
the class LdapProvisioning method addMembers.
@Override
public void addMembers(DistributionList list, String[] members) throws ServiceException {
LdapDistributionList ldl = (LdapDistributionList) list;
addDistributionListMembers(ldl, members);
}
Aggregations