Search in sources :

Example 1 with FilterId

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;
}
Also used : ZLdapFilter(com.zimbra.cs.ldap.ZLdapFilter) ExternalLdapConfig(com.zimbra.cs.ldap.LdapServerConfig.ExternalLdapConfig) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) LdapInvalidAttrValueException(com.zimbra.cs.ldap.LdapException.LdapInvalidAttrValueException) LdapSizeLimitExceededException(com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException) SearchLdapOptions(com.zimbra.cs.ldap.SearchLdapOptions) FilterId(com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId)

Example 2 with FilterId

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());
        }
    }
}
Also used : FilterId(com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId) LdapProv(com.zimbra.cs.account.ldap.LdapProv)

Example 3 with FilterId

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);
}
Also used : ZLdapFilter(com.zimbra.cs.ldap.ZLdapFilter) ObjectType(com.zimbra.cs.account.SearchDirectoryOptions.ObjectType) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain) FilterId(com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId)

Aggregations

FilterId (com.zimbra.cs.ldap.ZLdapFilterFactory.FilterId)3 ZLdapFilter (com.zimbra.cs.ldap.ZLdapFilter)2 Domain (com.zimbra.cs.account.Domain)1 ObjectType (com.zimbra.cs.account.SearchDirectoryOptions.ObjectType)1 LdapProv (com.zimbra.cs.account.ldap.LdapProv)1 LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)1 LdapInvalidAttrValueException (com.zimbra.cs.ldap.LdapException.LdapInvalidAttrValueException)1 LdapSizeLimitExceededException (com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException)1 ExternalLdapConfig (com.zimbra.cs.ldap.LdapServerConfig.ExternalLdapConfig)1 SearchLdapOptions (com.zimbra.cs.ldap.SearchLdapOptions)1 ZLdapContext (com.zimbra.cs.ldap.ZLdapContext)1