use of com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId 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.ZLdapFilterFactory.FilterId in project zm-mailbox by Zimbra.
the class ProvUtil method doSearchAccounts.
private void doSearchAccounts(String[] args) throws ServiceException, ArgException {
boolean verbose = false;
int i = 1;
if (args[i].equals("-v")) {
verbose = true;
i++;
if (args.length < i - 1) {
usage();
return;
}
}
if (args.length < i + 1) {
usage();
return;
}
String query = args[i];
Map<String, Object> attrs = getMap(args, i + 1);
String limitStr = (String) attrs.get("limit");
int limit = limitStr == null ? Integer.MAX_VALUE : Integer.parseInt(limitStr);
String offsetStr = (String) attrs.get("offset");
int offset = offsetStr == null ? 0 : Integer.parseInt(offsetStr);
String sortBy = (String) attrs.get("sortBy");
String sortAscending = (String) attrs.get("sortAscending");
boolean isSortAscending = (sortAscending != null) ? "1".equalsIgnoreCase(sortAscending) : true;
String[] attrsToGet = null;
String typesStr = (String) attrs.get("types");
if (typesStr == null) {
typesStr = SearchDirectoryOptions.ObjectType.accounts.name() + "," + SearchDirectoryOptions.ObjectType.aliases.name() + "," + SearchDirectoryOptions.ObjectType.distributionlists.name() + "," + SearchDirectoryOptions.ObjectType.dynamicgroups.name() + "," + SearchDirectoryOptions.ObjectType.resources.name();
}
String domainStr = (String) attrs.get("domain");
SearchDirectoryOptions searchOpts = new SearchDirectoryOptions(attrsToGet);
if (domainStr != null) {
Domain d = lookupDomain(domainStr, prov);
searchOpts.setDomain(d);
}
searchOpts.setTypes(typesStr);
searchOpts.setSortOpt(isSortAscending ? SortOpt.SORT_ASCENDING : SortOpt.SORT_DESCENDING);
searchOpts.setSortAttr(sortBy);
// if LdapClient is not initialized(the case for SoapProvisioning), FilterId
// is not initialized. Use null for SoapProvisioning, it will be set to
// FilterId.ADMIN_SEARCH in SearchDirectory soap handler.
FilterId filterId = (prov instanceof LdapProv) ? FilterId.ADMIN_SEARCH : null;
searchOpts.setFilterString(filterId, query);
// query must be already RFC 2254 escaped
searchOpts.setConvertIDNToAscii(true);
List<NamedEntry> accounts = prov.searchDirectory(searchOpts);
for (int j = offset; j < offset + limit && j < accounts.size(); j++) {
NamedEntry account = accounts.get(j);
if (verbose) {
if (account instanceof Account) {
dumpAccount((Account) account, true, null);
} else if (account instanceof Alias) {
dumpAlias((Alias) account);
} else if (account instanceof DistributionList) {
dumpGroup((DistributionList) account, null);
} else if (account instanceof Domain) {
dumpDomain((Domain) account, null);
}
} else {
console.println(account.getName());
}
}
}
use of com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId in project zm-mailbox by Zimbra.
the class LdapProvisioning method searchDirectoryInternal.
private List<NamedEntry> searchDirectoryInternal(SearchDirectoryOptions options, NamedEntry.Visitor visitor) throws ServiceException {
Set<ObjectType> types = options.getTypes();
if (types == null) {
throw ServiceException.INVALID_REQUEST("missing types", null);
}
/*
* base
*/
Domain domain = options.getDomain();
String[] bases = getSearchBases(domain, types);
/*
* filter
*/
int flags = options.getTypesAsFlags();
ZLdapFilter filter = options.getFilter();
String filterStr = options.getFilterString();
// exact one of filter or filterString has to be set
if (filter != null && filterStr != null) {
throw ServiceException.INVALID_REQUEST("only one of filter or filterString can be set", null);
}
if (filter == null) {
if (options.getConvertIDNToAscii() && !Strings.isNullOrEmpty(filterStr)) {
filterStr = LdapEntrySearchFilter.toLdapIDNFilter(filterStr);
}
// prepend objectClass filters
String objectClass = getObjectClassQuery(flags);
if (filterStr == null || filterStr.equals("")) {
filterStr = objectClass;
} else {
if (filterStr.startsWith("(") && filterStr.endsWith(")")) {
filterStr = "(&" + objectClass + filterStr + ")";
} else {
filterStr = "(&" + objectClass + "(" + filterStr + ")" + ")";
}
}
FilterId filterId = options.getFilterId();
if (filterId == null) {
throw ServiceException.INVALID_REQUEST("missing filter id", null);
}
filter = filterFactory.fromFilterString(options.getFilterId(), filterStr);
}
if (domain != null && !InMemoryLdapServer.isOn()) {
boolean groupsTree = false;
boolean peopleTree = false;
if (types.contains(ObjectType.dynamicgroups)) {
groupsTree = true;
}
if (types.contains(ObjectType.accounts) || types.contains(ObjectType.aliases) || types.contains(ObjectType.distributionlists) || types.contains(ObjectType.resources)) {
peopleTree = true;
}
if (groupsTree && peopleTree) {
ZLdapFilter dnSubtreeMatchFilter = ((LdapDomain) domain).getDnSubtreeMatchFilter();
filter = filterFactory.andWith(filter, dnSubtreeMatchFilter);
}
}
/*
* return attrs
*/
String[] returnAttrs = fixReturnAttrs(options.getReturnAttrs(), flags);
return searchObjects(bases, filter, returnAttrs, options, visitor);
}
Aggregations