use of com.zimbra.cs.ldap.ZMutableEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method copyCos.
private Cos copyCos(String srcCosId, String destCosName, Map<String, Object> cosAttrs) throws ServiceException {
destCosName = destCosName.toLowerCase().trim();
Cos srcCos = getCosById(srcCosId, null);
if (srcCos == null)
throw AccountServiceException.NO_SUCH_COS(srcCosId);
// bug 67716, use a case insensitive map because provided attr names may not be
// the canonical name and that will cause multiple entries in the map
Map<String, Object> allAttrs = new TreeMap<String, Object>(String.CASE_INSENSITIVE_ORDER);
allAttrs.putAll(srcCos.getAttrs());
allAttrs.remove(Provisioning.A_objectClass);
allAttrs.remove(Provisioning.A_zimbraId);
allAttrs.remove(Provisioning.A_zimbraCreateTimestamp);
allAttrs.remove(Provisioning.A_zimbraACE);
allAttrs.remove(Provisioning.A_cn);
allAttrs.remove(Provisioning.A_description);
if (cosAttrs != null) {
for (Map.Entry<String, Object> e : cosAttrs.entrySet()) {
String attr = e.getKey();
Object value = e.getValue();
if (value instanceof String && Strings.isNullOrEmpty((String) value)) {
allAttrs.remove(attr);
} else {
allAttrs.put(attr, value);
}
}
}
CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
//get rid of deprecated attrs
Map<String, Object> allNewAttrs = new HashMap<String, Object>(allAttrs);
for (String attr : allAttrs.keySet()) {
AttributeInfo info = AttributeManager.getInstance().getAttributeInfo(attr);
if (info != null && info.isDeprecated()) {
allNewAttrs.remove(attr);
}
}
allAttrs = allNewAttrs;
AttributeManager.getInstance().preModify(allAttrs, null, callbackContext, true);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_COS);
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.mapToAttrs(allAttrs);
Set<String> ocs = LdapObjectClass.getCosObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
String zimbraIdStr = LdapUtil.generateUUID();
entry.setAttr(A_zimbraId, zimbraIdStr);
entry.setAttr(A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()));
entry.setAttr(A_cn, destCosName);
String dn = mDIT.cosNametoDN(destCosName);
entry.setDN(dn);
zlc.createEntry(entry);
Cos cos = getCosById(zimbraIdStr, zlc);
AttributeManager.getInstance().postModify(allAttrs, cos, callbackContext);
return cos;
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.COS_EXISTS(destCosName);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to create cos: " + destCosName, e);
} finally {
LdapClient.closeContext(zlc);
}
}
use of com.zimbra.cs.ldap.ZMutableEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method createDomain.
@Override
public Domain createDomain(String name, Map<String, Object> domainAttrs) throws ServiceException {
name = name.toLowerCase().trim();
name = IDNUtil.toAsciiDomainName(name);
NameUtil.validNewDomainName(name);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_DOMAIN);
LdapDomain d = (LdapDomain) getDomainByAsciiName(name, zlc);
if (d != null) {
throw AccountServiceException.DOMAIN_EXISTS(name);
}
// Attribute checking can not express "allow setting on
// creation, but do not allow modifies afterwards"
String domainType = (String) domainAttrs.get(A_zimbraDomainType);
if (domainType == null) {
domainType = DomainType.local.name();
} else {
// add back later
domainAttrs.remove(A_zimbraDomainType);
}
String domainStatus = (String) domainAttrs.get(A_zimbraDomainStatus);
if (domainStatus == null) {
domainStatus = DOMAIN_STATUS_ACTIVE;
} else {
// add back later
domainAttrs.remove(A_zimbraDomainStatus);
}
String smimeLdapURL = (String) domainAttrs.get(A_zimbraSMIMELdapURL);
if (!StringUtil.isNullOrEmpty(smimeLdapURL)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapURL);
}
String smimeLdapStartTlsEnabled = (String) domainAttrs.get(A_zimbraSMIMELdapStartTlsEnabled);
if (!StringUtil.isNullOrEmpty(smimeLdapStartTlsEnabled)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapStartTlsEnabled);
}
String smimeLdapBindDn = (String) domainAttrs.get(A_zimbraSMIMELdapBindDn);
if (!StringUtil.isNullOrEmpty(smimeLdapBindDn)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapBindDn);
}
String smimeLdapBindPassword = (String) domainAttrs.get(A_zimbraSMIMELdapBindPassword);
if (!StringUtil.isNullOrEmpty(smimeLdapBindPassword)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapBindPassword);
}
String smimeLdapSearchBase = (String) domainAttrs.get(A_zimbraSMIMELdapSearchBase);
if (!StringUtil.isNullOrEmpty(smimeLdapSearchBase)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapSearchBase);
}
String smimeLdapFilter = (String) domainAttrs.get(A_zimbraSMIMELdapFilter);
if (!StringUtil.isNullOrEmpty(smimeLdapFilter)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapFilter);
}
String smimeLdapAttribute = (String) domainAttrs.get(A_zimbraSMIMELdapAttribute);
if (!StringUtil.isNullOrEmpty(smimeLdapAttribute)) {
// add back later
domainAttrs.remove(A_zimbraSMIMELdapAttribute);
}
CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
AttributeManager.getInstance().preModify(domainAttrs, null, callbackContext, true);
// Add back attrs we circumvented from attribute checking
domainAttrs.put(A_zimbraDomainType, domainType);
domainAttrs.put(A_zimbraDomainStatus, domainStatus);
domainAttrs.put(A_zimbraSMIMELdapURL, smimeLdapURL);
domainAttrs.put(A_zimbraSMIMELdapStartTlsEnabled, smimeLdapStartTlsEnabled);
domainAttrs.put(A_zimbraSMIMELdapBindDn, smimeLdapBindDn);
domainAttrs.put(A_zimbraSMIMELdapBindPassword, smimeLdapBindPassword);
domainAttrs.put(A_zimbraSMIMELdapSearchBase, smimeLdapSearchBase);
domainAttrs.put(A_zimbraSMIMELdapFilter, smimeLdapFilter);
domainAttrs.put(A_zimbraSMIMELdapAttribute, smimeLdapAttribute);
String[] parts = name.split("\\.");
String[] dns = mDIT.domainToDNs(parts);
createParentDomains(zlc, parts, dns);
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.mapToAttrs(domainAttrs);
Set<String> ocs = LdapObjectClass.getDomainObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
String zimbraIdStr = LdapUtil.generateUUID();
entry.setAttr(A_zimbraId, zimbraIdStr);
entry.setAttr(A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()));
entry.setAttr(A_zimbraDomainName, name);
String mailStatus = (String) domainAttrs.get(A_zimbraMailStatus);
if (mailStatus == null)
entry.setAttr(A_zimbraMailStatus, MAIL_STATUS_ENABLED);
if (domainType.equalsIgnoreCase(DomainType.alias.name())) {
entry.setAttr(A_zimbraMailCatchAllAddress, "@" + name);
}
entry.setAttr(A_o, name + " domain");
entry.setAttr(A_dc, parts[0]);
String dn = dns[0];
entry.setDN(dn);
//NOTE: all four of these should be in a transaction...
try {
zlc.createEntry(entry);
} catch (LdapEntryAlreadyExistException e) {
zlc.replaceAttributes(dn, entry.getAttributes());
}
String acctBaseDn = mDIT.domainDNToAccountBaseDN(dn);
if (!acctBaseDn.equals(dn)) {
/*
* create the account base dn entry only if if is not the same as the domain dn
*
* TODO, the objectclass(organizationalRole) and attrs(ou and cn) for the account
* base dn entry is still hardcoded, it should be parameterized in LdapDIT
* according the BASE_RDN_ACCOUNT. This is actually a design decision depending
* on how far we want to allow the DIT to be customized.
*/
zlc.createEntry(mDIT.domainDNToAccountBaseDN(dn), "organizationalRole", new String[] { A_ou, "people", A_cn, "people" });
// create the base DN for dynamic groups
zlc.createEntry(mDIT.domainDNToDynamicGroupsBaseDN(dn), "organizationalRole", new String[] { A_cn, "groups", A_description, "dynamic groups base" });
}
Domain domain = getDomainById(zimbraIdStr, zlc);
AttributeManager.getInstance().postModify(domainAttrs, domain, callbackContext);
return domain;
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.DOMAIN_EXISTS(name);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to create domain: " + name, e);
} finally {
LdapClient.closeContext(zlc);
}
}
use of com.zimbra.cs.ldap.ZMutableEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method renameDynamicGroup.
private void renameDynamicGroup(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_DYNAMICGROUP);
LdapDynamicGroup group = (LdapDynamicGroup) getDynamicGroupById(zimbraId, zlc, false);
if (group == null) {
throw AccountServiceException.NO_SUCH_DISTRIBUTION_LIST(zimbraId);
}
// prune cache
groupCache.remove(group);
String oldEmail = group.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(group, 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(group, 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(group, Provisioning.A_zimbraPrefAllowAddressForDelegatedSender, oldEmail, newEmail);
if (replacedAllowAddrForDelegatedSender.newAddrs().length > 0) {
attrs.put(Provisioning.A_zimbraPrefAllowAddressForDelegatedSender, replacedAllowAddrForDelegatedSender.newAddrs());
}
// the naming rdn
String rdnAttrName = mDIT.dynamicGroupNamingRdnAttr();
attrs.put(rdnAttrName, newLocal);
// move over the distribution list entry
String oldDn = group.getDN();
String newDn = mDIT.dynamicGroupDNRename(oldDn, newLocal, domain.getName());
boolean dnChanged = (!oldDn.equals(newDn));
if (dnChanged) {
// cn 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_cn);
zlc.renameEntry(oldDn, newDn);
}
// re-get the entry after move
group = (LdapDynamicGroup) getDynamicGroupById(zimbraId, zlc, false);
// doesn't throw exceptions, just logs
if (domainChanged) {
String newUid = group.getAttr(rdnAttrName);
moveAliases(zlc, replacedAliases, newDomain, newUid, oldDn, newDn, oldDomain, newDomain);
}
// could fail. So catch service exception here and log error
try {
// modify attrs on the mail entry
modifyAttrsInternal(group, zlc, attrs);
if (group.isIsACLGroup()) {
// modify attrs on the units (which are only present when group is an ACL Group)
String dynamicUnitNewLocal = dynamicGroupDynamicUnitLocalpart(newLocal);
String dynamicUnitNewEmail = dynamicUnitNewLocal + "@" + newDomain;
String dynamicUnitDN = mDIT.dynamicGroupUnitNameToDN(DYNAMIC_GROUP_DYNAMIC_UNIT_NAME, newDn);
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.setAttr(A_mail, dynamicUnitNewEmail);
entry.setAttr(A_zimbraMailAlias, dynamicUnitNewEmail);
zlc.replaceAttributes(dynamicUnitDN, entry.getAttributes());
}
} catch (ServiceException e) {
ZimbraLog.account.error("dynamic group renamed to " + newLocal + " but failed to move old name's LDAP attributes", e);
throw e;
}
removeExternalAddrsFromAllDynamicGroups(group.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 dynamic group: " + zimbraId, e);
} finally {
LdapClient.closeContext(zlc);
}
if (domainChanged) {
PermissionCache.invalidateCache();
}
}
use of com.zimbra.cs.ldap.ZMutableEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method createUCService.
@Override
public UCService createUCService(String name, Map<String, Object> attrs) throws ServiceException {
name = name.toLowerCase().trim();
CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
AttributeManager.getInstance().preModify(attrs, null, callbackContext, true);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_UCSERVICE);
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.mapToAttrs(attrs);
Set<String> ocs = LdapObjectClass.getUCServiceObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
String zimbraIdStr = LdapUtil.generateUUID();
entry.setAttr(A_zimbraId, zimbraIdStr);
entry.setAttr(A_zimbraCreateTimestamp, LdapDateUtil.toGeneralizedTime(new Date()));
entry.setAttr(A_cn, name);
String dn = mDIT.ucServiceNameToDN(name);
entry.setDN(dn);
zlc.createEntry(entry);
UCService ucService = getUCServiceById(zimbraIdStr, zlc, true);
AttributeManager.getInstance().postModify(attrs, ucService, callbackContext);
return ucService;
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.SERVER_EXISTS(name);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to create ucservice: " + name, e);
} finally {
LdapClient.closeContext(zlc);
}
}
use of com.zimbra.cs.ldap.ZMutableEntry in project zm-mailbox by Zimbra.
the class LdapProvisioning method createShareLocator.
@Override
public ShareLocator createShareLocator(String id, Map<String, Object> attrs) throws ServiceException {
CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
AttributeManager.getInstance().preModify(attrs, null, callbackContext, true);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_SHARELOCATOR);
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.mapToAttrs(attrs);
Set<String> ocs = LdapObjectClass.getShareLocatorObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
entry.setAttr(A_cn, id);
String dn = mDIT.shareLocatorIdToDN(id);
entry.setDN(dn);
zlc.createEntry(entry);
ShareLocator shloc = getShareLocatorById(id, zlc, true);
AttributeManager.getInstance().postModify(attrs, shloc, callbackContext);
return shloc;
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.SHARE_LOCATOR_EXISTS(id);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to create share locator: " + id, e);
} finally {
LdapClient.closeContext(zlc);
}
}
Aggregations