use of com.zimbra.cs.account.Domain in project zm-mailbox by Zimbra.
the class ADGroupHandler method getDelegatedAdminGroups.
private List<String> getDelegatedAdminGroups(Account acct, boolean asAdmin) throws ServiceException {
LdapProv prov = LdapProv.getInst();
Domain domain = prov.getDomain(acct);
if (domain == null) {
throw ServiceException.FAILURE("unable to get domain for account " + acct.getName(), null);
}
// try explicit external DN on account first
String extDN = acct.getAuthLdapExternalDn();
if (extDN == null) {
// then try bind DN template on domain
// note: for AD auth, zimbraAuthLdapSearchFilter is not used, so we
// skip that. See LdapProvisioning.externalLdapAuth
String dnTemplate = domain.getAuthLdapBindDn();
if (dnTemplate != null) {
extDN = LdapUtil.computeDn(acct.getName(), dnTemplate);
}
}
if (extDN == null) {
throw ServiceException.FAILURE("unable to get external DN for account " + acct.getName(), null);
}
ZLdapContext zlc = null;
try {
zlc = getExternalDelegatedAdminGroupsLdapContext(domain, asAdmin);
ZAttributes attrs = prov.getHelper().getAttributes(zlc, extDN, new String[] { MEMBER_OF_ATTR });
return attrs.getMultiAttrStringAsList(MEMBER_OF_ATTR, CheckBinary.NOCHECK);
} finally {
LdapClient.closeContext(zlc);
}
}
use of com.zimbra.cs.account.Domain in project zm-mailbox by Zimbra.
the class ADGroupHandler method legitimateDelegatedAdminAsGroupMember.
/*
* Check:
* - zimbraAuthMechAdmin on the domain must be AD
* - domain of the account must be the same as the domain in the grant
*
* TODO: pass in auth token and validate that the auth was indeed via AD
*/
private boolean legitimateDelegatedAdminAsGroupMember(ExternalGroup group, Account acct, boolean asAdmin) throws ServiceException {
String zimbraDomainId = group.getZimbraDomainId();
Domain domain = Provisioning.getInstance().getDomain(acct);
if (domain == null) {
return false;
}
if (!domainAdminAuthMechIsAD(domain, asAdmin)) {
return false;
}
if (!domain.getId().equals(zimbraDomainId)) {
return false;
}
return true;
}
use of com.zimbra.cs.account.Domain in project zm-mailbox by Zimbra.
the class ChangePasswordListener method getHandler.
private static ChangePasswordListener getHandler(Account acct) throws ServiceException {
Domain domain = Provisioning.getInstance().getDomain(acct);
if (domain == null)
throw AccountServiceException.NO_SUCH_DOMAIN(acct.getDomainName());
String listenerName = domain.getAttr(Provisioning.A_zimbraPasswordChangeListener);
if (listenerName == null)
return null;
ChangePasswordListener listener = mExternalListeners.get(listenerName);
if (listener == null)
throw ServiceException.FAILURE("change password listener " + listenerName + " for account " + acct.getName() + " not found", null);
return listener;
}
use of com.zimbra.cs.account.Domain 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.Domain 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();
}
}
Aggregations