use of com.zimbra.cs.account.ldap.entry.LdapDomain 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.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.
the class LdapProvisioning method getDomainByForeignNameInternal.
private Domain getDomainByForeignNameInternal(String foreignName, GetFromDomainCacheOption option) throws ServiceException {
Domain d = domainCache.getByForeignName(foreignName, option);
if (d instanceof DomainCache.NonExistingDomain)
return null;
LdapDomain domain = (LdapDomain) d;
if (domain == null) {
domain = getDomainByQuery(filterFactory.domainByForeignName(foreignName), null);
domainCache.put(Key.DomainBy.foreignName, foreignName, domain);
}
return domain;
}
use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.
the class LdapProvisioning method getDomainByIdInternal.
private Domain getDomainByIdInternal(String zimbraId, ZLdapContext zlc, GetFromDomainCacheOption option) throws ServiceException {
if (zimbraId == null) {
return null;
}
Domain d = domainCache.getById(zimbraId, option);
if (d instanceof DomainCache.NonExistingDomain) {
return null;
}
LdapDomain domain = (LdapDomain) d;
if (domain == null) {
domain = getDomainByQuery(filterFactory.domainById(zimbraId), zlc);
domainCache.put(Key.DomainBy.id, zimbraId, domain);
}
return domain;
}
use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.
the class LdapProvisioning method getDomainByAsciiNameInternal.
private Domain getDomainByAsciiNameInternal(String name, ZLdapContext zlc, GetFromDomainCacheOption option) throws ServiceException {
Domain d = domainCache.getByName(name, option);
if (d instanceof DomainCache.NonExistingDomain)
return null;
LdapDomain domain = (LdapDomain) d;
if (domain == null) {
domain = getDomainByQuery(filterFactory.domainByName(name), zlc);
domainCache.put(Key.DomainBy.name, name, domain);
}
return domain;
}
use of com.zimbra.cs.account.ldap.entry.LdapDomain in project zm-mailbox by Zimbra.
the class LdapProvisioning method createDynamicGroup.
private DynamicGroup createDynamicGroup(String groupAddress, Map<String, Object> groupAttrs, Account creator) throws ServiceException {
SpecialAttrs specialAttrs = mDIT.handleSpecialAttrs(groupAttrs);
String baseDn = specialAttrs.getLdapBaseDn();
groupAddress = groupAddress.toLowerCase().trim();
EmailAddress addr = new EmailAddress(groupAddress);
String localPart = addr.getLocalPart();
String domainName = addr.getDomain();
domainName = IDNUtil.toAsciiDomainName(domainName);
groupAddress = EmailAddress.getAddress(localPart, domainName);
validEmailAddress(groupAddress);
CallbackContext callbackContext = new CallbackContext(CallbackContext.Op.CREATE);
callbackContext.setCreatingEntryName(groupAddress);
// remove zimbraIsACLGroup from attrs if provided, to avoid the immutable check
Object providedZimbraIsACLGroup = groupAttrs.get(A_zimbraIsACLGroup);
if (providedZimbraIsACLGroup != null) {
groupAttrs.remove(A_zimbraIsACLGroup);
}
AttributeManager.getInstance().preModify(groupAttrs, null, callbackContext, true);
// put zimbraIsACLGroup back
if (providedZimbraIsACLGroup != null) {
groupAttrs.put(A_zimbraIsACLGroup, providedZimbraIsACLGroup);
}
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.CREATE_DYNAMICGROUP);
Domain domain = getDomainByAsciiName(domainName, zlc);
if (domain == null) {
throw AccountServiceException.NO_SUCH_DOMAIN(domainName);
}
if (!domain.isLocal()) {
throw ServiceException.INVALID_REQUEST("domain type must be local", null);
}
String domainDN = ((LdapDomain) domain).getDN();
/*
* ====================================
* create the main dynamic group entry
* ====================================
*/
ZMutableEntry entry = LdapClient.createMutableEntry();
entry.mapToAttrs(groupAttrs);
Set<String> ocs = LdapObjectClass.getGroupObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
String zimbraId = LdapUtil.generateUUID();
// create a UUID for the static unit entry
String staticUnitZimbraId = LdapUtil.generateUUID();
String createTimestamp = LdapDateUtil.toGeneralizedTime(new Date());
entry.setAttr(A_zimbraId, zimbraId);
entry.setAttr(A_zimbraCreateTimestamp, createTimestamp);
entry.setAttr(A_mail, groupAddress);
entry.setAttr(A_dgIdentity, LC.zimbra_ldap_userdn.value());
// unlike accounts (which have a zimbraMailDeliveryAddress for the primary,
// and zimbraMailAliases only for aliases), DLs use zimbraMailAlias for both.
// Postfix uses these two attributes to route mail, and zimbraMailDeliveryAddress
// indicates that something has a physical mailbox, which DLs don't.
entry.setAttr(A_zimbraMailAlias, groupAddress);
/*
// allow only users in the same domain
String memberURL = String.format("ldap:///%s??one?(zimbraMemberOf=%s)",
mDIT.domainDNToAccountBaseDN(domainDN), groupAddress);
*/
String specifiedIsACLGroup = entry.getAttrString(A_zimbraIsACLGroup);
boolean isACLGroup;
if (!entry.hasAttribute(A_memberURL)) {
String memberURL = LdapDynamicGroup.getDefaultMemberURL(zimbraId, staticUnitZimbraId);
entry.setAttr(Provisioning.A_memberURL, memberURL);
// or specified to be TRUE;
if (specifiedIsACLGroup == null) {
entry.setAttr(A_zimbraIsACLGroup, ProvisioningConstants.TRUE);
} else if (ProvisioningConstants.FALSE.equals(specifiedIsACLGroup)) {
throw ServiceException.INVALID_REQUEST("No custom " + A_memberURL + " is provided, " + A_zimbraIsACLGroup + " cannot be set to FALSE", null);
}
isACLGroup = true;
} else {
// We want to be able to use dynamic groups as ACLs, for instance when sharing a folder with a group
// This used to be disallowed via a requirement that zimbraIsACLGroup be specified and set to FALSE.
// That requirement has been dropped.
isACLGroup = !ProvisioningConstants.FALSE.equals(specifiedIsACLGroup);
}
// by default a dynamic group is always created enabled
if (!entry.hasAttribute(Provisioning.A_zimbraMailStatus)) {
entry.setAttr(A_zimbraMailStatus, MAIL_STATUS_ENABLED);
}
String mailStatus = entry.getAttrString(A_zimbraMailStatus);
entry.setAttr(A_cn, localPart);
// entry.setAttr(A_uid, localPart); need to use uid if we move dynamic groups to the ou=people tree
setGroupHomeServer(entry, creator);
String dn = mDIT.dynamicGroupNameLocalPartToDN(localPart, domainDN);
entry.setDN(dn);
zlc.createEntry(entry);
if (isACLGroup) {
/*
* ===========================================================
* create the dynamic group unit entry, for internal addresses
* ===========================================================
*/
String dynamicUnitLocalpart = dynamicGroupDynamicUnitLocalpart(localPart);
String dynamicUnitAddr = EmailAddress.getAddress(dynamicUnitLocalpart, domainName);
entry = LdapClient.createMutableEntry();
ocs = LdapObjectClass.getGroupDynamicUnitObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
String dynamicUnitZimbraId = LdapUtil.generateUUID();
entry.setAttr(A_cn, DYNAMIC_GROUP_DYNAMIC_UNIT_NAME);
entry.setAttr(A_zimbraId, dynamicUnitZimbraId);
// id of the main group
entry.setAttr(A_zimbraGroupId, zimbraId);
entry.setAttr(A_zimbraCreateTimestamp, createTimestamp);
entry.setAttr(A_mail, dynamicUnitAddr);
entry.setAttr(A_zimbraMailAlias, dynamicUnitAddr);
entry.setAttr(A_zimbraMailStatus, mailStatus);
entry.setAttr(A_dgIdentity, LC.zimbra_ldap_userdn.value());
// id of the main group
String memberURL = LdapDynamicGroup.getDefaultDynamicUnitMemberURL(zimbraId);
entry.setAttr(Provisioning.A_memberURL, memberURL);
String dynamicUnitDN = mDIT.dynamicGroupUnitNameToDN(DYNAMIC_GROUP_DYNAMIC_UNIT_NAME, dn);
entry.setDN(dynamicUnitDN);
zlc.createEntry(entry);
/*
* ==========================================================
* create the static group unit entry, for external addresses
* ==========================================================
*/
entry = LdapClient.createMutableEntry();
ocs = LdapObjectClass.getGroupStaticUnitObjectClasses(this);
entry.addAttr(A_objectClass, ocs);
entry.setAttr(A_cn, DYNAMIC_GROUP_STATIC_UNIT_NAME);
entry.setAttr(A_zimbraId, staticUnitZimbraId);
// id of the main group
entry.setAttr(A_zimbraGroupId, zimbraId);
entry.setAttr(A_zimbraCreateTimestamp, createTimestamp);
String staticUnitDN = mDIT.dynamicGroupUnitNameToDN(DYNAMIC_GROUP_STATIC_UNIT_NAME, dn);
entry.setDN(staticUnitDN);
zlc.createEntry(entry);
}
/*
* all is well, get the group by id
*/
DynamicGroup group = getDynamicGroupBasic(DistributionListBy.id, zimbraId, zlc);
if (group != null) {
AttributeManager.getInstance().postModify(groupAttrs, group, callbackContext);
removeExternalAddrsFromAllDynamicGroups(group.getAllAddrsSet(), zlc);
allDLs.addGroup(group);
} else {
throw ServiceException.FAILURE("unable to get dynamic group after creating LDAP entry: " + groupAddress, null);
}
return group;
} catch (LdapEntryAlreadyExistException nabe) {
throw AccountServiceException.DISTRIBUTION_LIST_EXISTS(groupAddress);
} catch (LdapException e) {
throw e;
} catch (AccountServiceException e) {
throw e;
} finally {
LdapClient.closeContext(zlc);
}
}
Aggregations