use of com.zimbra.cs.ldap.LdapException.LdapInvalidAttrValueException 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;
}
Aggregations