use of com.zimbra.cs.ldap.ZLdapContext in project zm-mailbox by Zimbra.
the class LdapProvisioning method deleteAlwaysOnCluster.
@Override
public void deleteAlwaysOnCluster(String zimbraId) throws ServiceException {
LdapAlwaysOnCluster cluster = (LdapAlwaysOnCluster) getAlwaysOnClusterByIdInternal(zimbraId);
if (cluster == null)
throw AccountServiceException.NO_SUCH_ALWAYSONCLUSTER(zimbraId);
ZLdapContext zlc = null;
try {
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.DELETE_ALWAYSONCLUSTER);
zlc.deleteEntry(cluster.getDN());
alwaysOnClusterCache.remove(cluster);
} catch (ServiceException e) {
throw ServiceException.FAILURE("unable to purge alwaysOnCluster: " + zimbraId, e);
} finally {
LdapClient.closeContext(zlc);
}
}
use of com.zimbra.cs.ldap.ZLdapContext 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.ZLdapContext in project zm-mailbox by Zimbra.
the class AutoProvision method getExternalAttrsByName.
protected ExternalEntry getExternalAttrsByName(String loginName) throws ServiceException {
String url = domain.getAutoProvLdapURL();
boolean wantStartTLS = domain.isAutoProvLdapStartTlsEnabled();
String adminDN = domain.getAutoProvLdapAdminBindDn();
String adminPassword = domain.getAutoProvLdapAdminBindPassword();
String[] attrs = getAttrsToFetch();
// always use the admin bind DN/password, not the user's bind DN/password
ExternalLdapConfig config = new ExternalLdapConfig(url, wantStartTLS, null, adminDN, adminPassword, null, "auto provision account");
ZLdapContext zlc = null;
try {
zlc = LdapClient.getExternalContext(config, LdapUsage.AUTO_PROVISION);
String searchFilterTemplate = domain.getAutoProvLdapSearchFilter();
if (searchFilterTemplate != null) {
// get attrs by search
String searchBase = domain.getAutoProvLdapSearchBase();
if (searchBase == null) {
searchBase = LdapConstants.DN_ROOT_DSE;
}
String searchFilter = LdapUtil.computeDn(loginName, searchFilterTemplate);
ZimbraLog.autoprov.debug("AutoProvision: computed search filter" + searchFilter);
ZSearchResultEntry entry = prov.getHelper().searchForEntry(searchBase, ZLdapFilterFactory.getInstance().fromFilterString(FilterId.AUTO_PROVISION_SEARCH, searchFilter), zlc, attrs);
if (entry == null) {
throw AccountServiceException.NO_SUCH_EXTERNAL_ENTRY(loginName);
}
return new ExternalEntry(entry.getDN(), entry.getAttributes());
}
String bindDNTemplate = domain.getAutoProvLdapBindDn();
if (bindDNTemplate != null) {
// get attrs by external DN template
String dn = LdapUtil.computeDn(loginName, bindDNTemplate);
ZimbraLog.autoprov.debug("AutoProvision: computed external DN" + dn);
return new ExternalEntry(dn, prov.getHelper().getAttributes(zlc, dn, attrs));
}
} finally {
LdapClient.closeContext(zlc);
}
throw ServiceException.FAILURE("One of " + Provisioning.A_zimbraAutoProvLdapBindDn + " or " + Provisioning.A_zimbraAutoProvLdapSearchFilter + " must be set", null);
}
use of com.zimbra.cs.ldap.ZLdapContext in project zm-mailbox by Zimbra.
the class AutoProvision method searchAutoProvDirectory.
/**
* Search the external auto provision LDAP source
*
* Only one of filter or name can be provided.
* - if name is provided, the search filter will be zimbraAutoProvLdapSearchFilter
* with place holders filled with the name.
*
* - if filter is provided, the provided filter will be the search filter.
*
* - if neither is provided, the search filter will be zimbraAutoProvLdapSearchFilter
* with place holders filled with "*". If createTimestampLaterThan
* is provided, the search filter will be ANDed with (createTimestamp >= {timestamp})
*
* @param prov
* @param domain
* @param filter
* @param name
* @param createTimestampLaterThan
* @param returnAttrs
* @param maxResults
* @param ldapVisitor
* @param wantPartialResult whether TOO_MANY_SEARCH_RESULTS should be thrown if the
* ldap search encountered LdapSizeLimitExceededException
* Note: regardless of this parameter, the ldapVisitor.visit
* is called for each entry returned from LDAP.
* This behavior is currently hardcoded in
* UBIDLdapContext.searchPaged and has been the legacy behavior.
* We can probably change it into a parameter in SearchLdapOptions.
* @throws ServiceException
* @return whether LdapSizeLimitExceededException was hit
*/
static boolean searchAutoProvDirectory(LdapProv prov, Domain domain, String filter, String name, String createTimestampLaterThan, String[] returnAttrs, int maxResults, SearchLdapVisitor ldapVisitor, boolean wantPartialResult) throws ServiceException {
// use either filter or name, make sure only one is provided
if ((filter != null) && (name != null)) {
throw ServiceException.INVALID_REQUEST("only one of filter or name can be provided", null);
}
String url = domain.getAutoProvLdapURL();
boolean wantStartTLS = domain.isAutoProvLdapStartTlsEnabled();
String adminDN = domain.getAutoProvLdapAdminBindDn();
String adminPassword = domain.getAutoProvLdapAdminBindPassword();
String searchBase = domain.getAutoProvLdapSearchBase();
String searchFilterTemplate = domain.getAutoProvLdapSearchFilter();
FilterId filterId = FilterId.AUTO_PROVISION_SEARCH;
if (url == null) {
throw ServiceException.FAILURE(String.format("missing %s on domain %s", Provisioning.A_zimbraAutoProvLdapURL, domain.getName()), null);
}
if (searchBase == null) {
searchBase = LdapConstants.DN_ROOT_DSE;
}
ExternalLdapConfig config = new ExternalLdapConfig(url, wantStartTLS, null, adminDN, adminPassword, null, "search auto provision directory");
boolean hitSizeLimitExceededException = false;
ZLdapContext zlc = null;
ZLdapFilter zFilter = null;
try {
zlc = LdapClient.getExternalContext(config, LdapUsage.AUTO_PROVISION_ADMIN_SEARCH);
String searchFilter = null;
String searchFilterWithoutLastPolling = null;
if (name != null) {
if (searchFilterTemplate == null) {
throw ServiceException.INVALID_REQUEST("search filter template is not set on domain " + domain.getName(), null);
}
searchFilter = LdapUtil.computeDn(name, searchFilterTemplate);
} else if (filter != null) {
searchFilter = filter;
filterId = FilterId.AUTO_PROVISION_ADMIN_SEARCH;
} else {
if (searchFilterTemplate == null) {
throw ServiceException.INVALID_REQUEST("search filter template is not set on domain " + domain.getName(), null);
}
searchFilter = LdapUtil.computeDn("*", searchFilterTemplate);
if (createTimestampLaterThan != null) {
searchFilterWithoutLastPolling = searchFilter;
// searchFilter = "(&" + searchFilter + "(createTimestamp>=" + createTimestampLaterThan + "))";
searchFilter = "(&" + searchFilter + ZLdapFilterFactory.getInstance().createdLaterOrEqual(createTimestampLaterThan).toFilterString() + ")";
filterId = FilterId.AUTO_PROVISION_SEARCH_CREATED_LATERTHAN;
}
}
zFilter = ZLdapFilterFactory.getInstance().fromFilterString(filterId, searchFilter);
SearchLdapOptions searchOptions;
try {
searchOptions = new SearchLdapOptions(searchBase, zFilter, returnAttrs, maxResults, null, ZSearchScope.SEARCH_SCOPE_SUBTREE, ldapVisitor);
zlc.searchPaged(searchOptions);
} catch (LdapInvalidAttrValueException eav) {
ZimbraLog.autoprov.info("Retrying ldap search query with createTimestamp in seconds.");
if (searchFilterWithoutLastPolling != null && createTimestampLaterThan != null) {
createTimestampLaterThan = createTimestampLaterThan.replaceAll("\\..*Z$", "Z");
// searchFilter = "(&" + searchFilter + "(createTimestamp>=" + createTimestampLaterThan + "))";
searchFilter = "(&" + searchFilterWithoutLastPolling + ZLdapFilterFactory.getInstance().createdLaterOrEqual(createTimestampLaterThan).toFilterString() + ")";
ZimbraLog.autoprov.info("new searchFilter = %s", searchFilter);
filterId = FilterId.AUTO_PROVISION_SEARCH_CREATED_LATERTHAN;
}
zFilter = ZLdapFilterFactory.getInstance().fromFilterString(filterId, searchFilter);
searchOptions = new SearchLdapOptions(searchBase, zFilter, returnAttrs, maxResults, null, ZSearchScope.SEARCH_SCOPE_SUBTREE, ldapVisitor);
zlc.searchPaged(searchOptions);
}
} catch (LdapSizeLimitExceededException e) {
hitSizeLimitExceededException = true;
if (wantPartialResult) {
// log at debug level
ZimbraLog.autoprov.debug(String.format("searchAutoProvDirectory encountered LdapSizeLimitExceededException: " + "base=%s, filter=%s", searchBase, zFilter == null ? "" : zFilter.toFilterString()), e);
} else {
throw AccountServiceException.TOO_MANY_SEARCH_RESULTS("too many search results returned", e);
}
} finally {
LdapClient.closeContext(zlc);
}
return hitSizeLimitExceededException;
}
use of com.zimbra.cs.ldap.ZLdapContext in project zm-mailbox by Zimbra.
the class AutoProvisionEager method handleScheduledDomains.
static void handleScheduledDomains(LdapProv prov, EagerAutoProvisionScheduler scheduler) {
ZLdapContext zlc = null;
try {
// get scheduled domains on this server
Server localServer = prov.getLocalServer();
String[] scheduledDomains = localServer.getAutoProvScheduledDomains();
zlc = LdapClient.getContext(LdapServerType.MASTER, LdapUsage.AUTO_PROVISION);
for (String domainName : scheduledDomains) {
if (scheduler.isShutDownRequested()) {
ZimbraLog.autoprov.info("eager auto provision aborted");
return;
}
try {
Domain domain = prov.get(DomainBy.name, domainName);
if (domain == null) {
ZimbraLog.autoprov.info("EAGER auto provision: no such domain " + domainName);
continue;
}
// refresh the domain from LDAP master so we don't get into a race
// condition if the domains was just enabled for EAGER mode on other node.
prov.reload(domain, true);
if (!autoProvisionEnabled(domain)) {
/*
* remove it from the scheduled domains on the local server
*/
ZimbraLog.autoprov.info("Domain %s is scheduled for EAGER auto provision " + "but EAGER mode is not enabled on the domain. " + "Removing domain %s from %s on server %s", domain.getName(), domain.getName(), Provisioning.A_zimbraAutoProvScheduledDomains, localServer.getName());
// will trigger callback for AutoProvScheduledDomains. If scheduled
// domains become empty, the EAGER auto prov thread will be requested
// to shutdown.
localServer.removeAutoProvScheduledDomains(domain.getName());
continue;
}
ZimbraLog.autoprov.info("Auto provisioning accounts on domain %s", domainName);
AutoProvisionEager autoProv = new AutoProvisionEager(prov, domain, scheduler);
autoProv.handleBatch(zlc);
} catch (Throwable t) {
if (t instanceof OutOfMemoryError) {
Zimbra.halt("Ran out of memory while auto provision accounts", t);
} else {
ZimbraLog.autoprov.warn("Unable to auto provision accounts for domain %s", domainName, t);
}
}
}
} catch (ServiceException e) {
// unable to get ldap context
ZimbraLog.autoprov.warn("Unable to auto provision accounts", e);
} finally {
LdapClient.closeContext(zlc);
}
}
Aggregations