Search in sources :

Example 1 with LdapSizeLimitExceededException

use of com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException 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 LdapSizeLimitExceededException

use of com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException in project zm-mailbox by Zimbra.

the class LdapGalSearch method searchGal.

public static void searchGal(ZLdapContext zlc, GalSearchConfig.GalType galType, int pageSize, String base, String query, int maxResults, LdapGalMapRules rules, String token, SearchGalResult result, GalOp op) throws ServiceException {
    String tk = token != null && !token.equals("") ? token : LdapConstants.EARLIEST_SYNC_TOKEN;
    result.setToken(tk);
    if (GalOp.sync == op) {
        String maxLdapTs = result.getMaxLdapTimeStamp();
        if (!StringUtils.isEmpty(maxLdapTs)) {
            result.setToken(maxLdapTs);
        }
    }
    String[] reqAttrs = rules.getLdapAttrs();
    if (ZimbraLog.gal.isDebugEnabled()) {
        StringBuffer returnAttrs = new StringBuffer();
        for (String a : reqAttrs) {
            returnAttrs.append(a + ",");
        }
        zlc.debug();
        ZimbraLog.gal.debug("searchGal: " + ", page size=" + pageSize + ", max results=" + maxResults + ", base=" + base + ", query=" + query + ", attrs=" + returnAttrs);
    }
    if (GalOp.sync == op) {
        result.setLimit(maxResults);
        maxResults = SearchLdapOptions.SIZE_UNLIMITED;
    }
    SearhcGalVisitor visitor = new SearhcGalVisitor(zlc, galType, base, rules, result);
    SearchLdapOptions searchOpts = new SearchLdapOptions(base, ZLdapFilterFactory.getInstance().fromFilterString(FilterId.GAL_SEARCH, query), reqAttrs, maxResults, null, ZSearchScope.SEARCH_SCOPE_SUBTREE, visitor);
    searchOpts.setResultPageSize(pageSize);
    searchOpts.setGalOp(op);
    if (GalOp.sync == op) {
        searchOpts.setSearchGalResult(result);
    }
    try {
        zlc.searchPaged(searchOpts);
    } catch (LdapSizeLimitExceededException sle) {
        result.setHadMore(true);
    } catch (ServiceException e) {
        throw ServiceException.FAILURE("unable to search gal", e);
    } finally {
        if (GalOp.sync != op || ((GalOp.sync == op) && !result.getHadMore())) {
            boolean gotNewToken = true;
            String newToken = result.getToken();
            if (newToken == null || (token != null && token.equals(newToken)) || newToken.equals(LdapConstants.EARLIEST_SYNC_TOKEN))
                gotNewToken = false;
            if (gotNewToken) {
                Date parsedToken = LdapDateUtil.parseGeneralizedTime(newToken);
                if (parsedToken != null) {
                    long ts = parsedToken.getTime();
                    ts += 1000;
                    // Note, this will "normalize" the token to our standard format
                    // DateUtil.ZIMBRA_LDAP_GENERALIZED_TIME_FORMAT
                    // Whenever we've got a new token, it will be returned in the
                    // normalized format.
                    String deltaToken = LdapDateUtil.toGeneralizedTime(new Date(ts));
                    result.setToken(deltaToken);
                    if (GalOp.sync == op) {
                        result.setLdapTimeStamp(deltaToken);
                    }
                }
            /*
                     * in the rare case when an LDAP implementation does not conform to generalized time and
                     * we cannot parser the token, just leave it alone.
                     */
            } else {
                //no records found
                if ((GalOp.sync == op) && !result.getHadMore()) {
                    result.setToken(newToken);
                    result.setLdapTimeStamp(newToken);
                }
            }
        }
    }
}
Also used : ServiceException(com.zimbra.common.service.ServiceException) LdapSizeLimitExceededException(com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException) SearchLdapOptions(com.zimbra.cs.ldap.SearchLdapOptions) Date(java.util.Date)

Example 3 with LdapSizeLimitExceededException

use of com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException in project zm-mailbox by Zimbra.

the class LdapProvisioning method searchLdapObjects.

private void searchLdapObjects(String base, ZLdapFilter filter, String[] returnAttrs, SearchDirectoryOptions opts, NamedEntry.Visitor visitor) throws ServiceException {
    ZLdapContext zlc = null;
    try {
        zlc = LdapClient.getContext(LdapServerType.get(opts.getOnMaster()), opts.getUseConnPool(), LdapUsage.SEARCH);
        SearchObjectsVisitor searchObjectsVisitor = new SearchObjectsVisitor(this, zlc, visitor, opts.getMaxResults(), opts.getMakeObjectOpt(), returnAttrs);
        SearchLdapOptions searchObjectsOptions = new SearchLdapOptions(base, filter, returnAttrs, opts.getMaxResults(), null, ZSearchScope.SEARCH_SCOPE_SUBTREE, searchObjectsVisitor);
        searchObjectsOptions.setUseControl(opts.isUseControl());
        searchObjectsOptions.setManageDSAit(opts.isManageDSAit());
        zlc.searchPaged(searchObjectsOptions);
    } catch (LdapSizeLimitExceededException e) {
        throw AccountServiceException.TOO_MANY_SEARCH_RESULTS("too many search results returned", e);
    } catch (ServiceException e) {
        throw ServiceException.FAILURE("unable to list all objects", e);
    } finally {
        LdapClient.closeContext(zlc);
    }
}
Also used : ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) LdapSizeLimitExceededException(com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException) SearchLdapOptions(com.zimbra.cs.ldap.SearchLdapOptions)

Example 4 with LdapSizeLimitExceededException

use of com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException in project zm-mailbox by Zimbra.

the class LdapProvisioning method deleteDomainInternal.

public void deleteDomainInternal(ZLdapContext zlc, String zimbraId) throws ServiceException {
    // TODO: should only allow a domain delete to succeed if there are no people
    // if there aren't, we need to delete the people trees first, then delete the domain.
    LdapDomain domain = null;
    String acctBaseDn = null;
    String dynGroupsBaseDn = null;
    try {
        domain = (LdapDomain) getDomainById(zimbraId, zlc);
        if (domain == null) {
            throw AccountServiceException.NO_SUCH_DOMAIN(zimbraId);
        }
        String name = domain.getName();
        // delete account base DN
        acctBaseDn = mDIT.domainDNToAccountBaseDN(domain.getDN());
        if (!acctBaseDn.equals(domain.getDN())) {
            try {
                zlc.deleteEntry(acctBaseDn);
            } catch (LdapEntryNotFoundException e) {
                ZimbraLog.account.info("entry %s not found", acctBaseDn);
            }
        }
        // delete dynamic groups base DN
        dynGroupsBaseDn = mDIT.domainDNToDynamicGroupsBaseDN(domain.getDN());
        if (!dynGroupsBaseDn.equals(domain.getDN())) {
            try {
                zlc.deleteEntry(dynGroupsBaseDn);
            } catch (LdapEntryNotFoundException e) {
                ZimbraLog.account.info("entry %s not found", dynGroupsBaseDn);
            }
        }
        try {
            zlc.deleteEntry(domain.getDN());
            domainCache.remove(domain);
        } catch (LdapContextNotEmptyException e) {
            // remove from cache before nuking all attrs
            domainCache.remove(domain);
            // assume subdomains exist and turn into plain dc object
            Map<String, String> attrs = new HashMap<String, String>();
            attrs.put("-" + A_objectClass, "zimbraDomain");
            // remove all zimbra attrs
            for (String key : domain.getAttrs(false).keySet()) {
                if (key.startsWith("zimbra"))
                    attrs.put(key, "");
            }
            // cannot invoke callback here.  If another domain attr is added in a callback,
            // e.g. zimbraDomainStatus would add zimbraMailStatus, then we will get a LDAP
            // schema violation naming error(zimbraDomain is removed, thus there cannot be
            // any zimbraAttrs left) and the modify will fail.
            modifyAttrs(domain, attrs, false, false);
        }
        String defaultDomain = getConfig().getAttr(A_zimbraDefaultDomainName, null);
        if (name.equalsIgnoreCase(defaultDomain)) {
            try {
                Map<String, String> attrs = new HashMap<String, String>();
                attrs.put(A_zimbraDefaultDomainName, "");
                modifyAttrs(getConfig(), attrs);
            } catch (Exception e) {
                ZimbraLog.account.warn("unable to remove config attr:" + A_zimbraDefaultDomainName, e);
            }
        }
    } catch (LdapContextNotEmptyException e) {
        // get a few entries to include in the error message
        int maxEntriesToGet = 5;
        final String doNotReportThisDN = acctBaseDn;
        final StringBuilder sb = new StringBuilder();
        sb.append(" (remaining entries: ");
        SearchLdapOptions.SearchLdapVisitor visitor = new SearchLdapOptions.SearchLdapVisitor() {

            @Override
            public void visit(String dn, Map<String, Object> attrs, IAttributes ldapAttrs) {
                if (!dn.equals(doNotReportThisDN)) {
                    sb.append("[" + dn + "] ");
                }
            }
        };
        SearchLdapOptions searchOptions = new SearchLdapOptions(acctBaseDn, filterFactory.anyEntry(), new String[] { Provisioning.A_objectClass }, maxEntriesToGet, null, ZSearchScope.SEARCH_SCOPE_SUBTREE, visitor);
        try {
            zlc.searchPaged(searchOptions);
        } catch (LdapSizeLimitExceededException lslee) {
        // quietly ignore
        } catch (ServiceException se) {
            ZimbraLog.account.warn("unable to get sample entries in non-empty domain " + domain.getName() + " for reporting", se);
        }
        sb.append("...)");
        throw AccountServiceException.DOMAIN_NOT_EMPTY(domain.getName() + sb.toString(), e);
    } catch (ServiceException e) {
        throw ServiceException.FAILURE("unable to purge domain: " + zimbraId, e);
    }
}
Also used : HashMap(java.util.HashMap) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) SearchLdapOptions(com.zimbra.cs.ldap.SearchLdapOptions) LdapContextNotEmptyException(com.zimbra.cs.ldap.LdapException.LdapContextNotEmptyException) AccountServiceException(com.zimbra.cs.account.AccountServiceException) ZimletException(com.zimbra.cs.zimlet.ZimletException) LdapEntryNotFoundException(com.zimbra.cs.ldap.LdapException.LdapEntryNotFoundException) IOException(java.io.IOException) LdapInvalidSearchFilterException(com.zimbra.cs.ldap.LdapException.LdapInvalidSearchFilterException) StopIteratingException(com.zimbra.cs.ldap.SearchLdapOptions.StopIteratingException) LdapInvalidAttrValueException(com.zimbra.cs.ldap.LdapException.LdapInvalidAttrValueException) LdapContextNotEmptyException(com.zimbra.cs.ldap.LdapException.LdapContextNotEmptyException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) LdapEntryAlreadyExistException(com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException) ServiceException(com.zimbra.common.service.ServiceException) LdapException(com.zimbra.cs.ldap.LdapException) LdapMultipleEntriesMatchedException(com.zimbra.cs.ldap.LdapException.LdapMultipleEntriesMatchedException) PatternSyntaxException(java.util.regex.PatternSyntaxException) LdapSizeLimitExceededException(com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException) LdapInvalidAttrNameException(com.zimbra.cs.ldap.LdapException.LdapInvalidAttrNameException) SearchLdapVisitor(com.zimbra.cs.ldap.SearchLdapOptions.SearchLdapVisitor) SearchLdapVisitor(com.zimbra.cs.ldap.SearchLdapOptions.SearchLdapVisitor) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) LdapEntryNotFoundException(com.zimbra.cs.ldap.LdapException.LdapEntryNotFoundException) IAttributes(com.zimbra.cs.ldap.IAttributes) LdapSizeLimitExceededException(com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException) Map(java.util.Map) TreeMap(java.util.TreeMap) HashMap(java.util.HashMap)

Example 5 with LdapSizeLimitExceededException

use of com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException in project zm-mailbox by Zimbra.

the class LdapExample method search.

public void search() throws Exception {
    String base = "cn=servers,cn=zimbra";
    String filter = "(objectClass=zimbraServer)";
    String[] returnAttrs = new String[] { "objectClass", "cn" };
    ZLdapFilter zFilter = ZLdapFilterFactory.getInstance().fromFilterString(FilterId.ZMCONFIGD, filter);
    ZSearchControls searchControls = ZSearchControls.createSearchControls(ZSearchScope.SEARCH_SCOPE_SUBTREE, ZSearchControls.SIZE_UNLIMITED, returnAttrs);
    GenericLdapConfig ldapConfig = getLdapConfig();
    ZLdapContext zlc = null;
    try {
        zlc = LdapClient.getContext(ldapConfig, LdapUsage.SEARCH);
        ZSearchResultEnumeration ne = zlc.searchDir(base, zFilter, searchControls);
        while (ne.hasMore()) {
            ZSearchResultEntry entry = ne.next();
            String dn = entry.getDN();
            ZAttributes attrs = entry.getAttributes();
            String cn = attrs.getAttrString("cn");
            String[] objectClasses = attrs.getMultiAttrString("objectClass");
            System.out.println("dn = " + dn);
            System.out.println("cn = " + cn);
            for (String objectClass : objectClasses) {
                System.out.println("objetClass = " + objectClass);
            }
        }
        ne.close();
    } catch (LdapSizeLimitExceededException e) {
        e.printStackTrace();
        throw e;
    } finally {
        // Note: this is important!! 
        LdapClient.closeContext(zlc);
    }
}
Also used : ZLdapFilter(com.zimbra.cs.ldap.ZLdapFilter) ZSearchControls(com.zimbra.cs.ldap.ZSearchControls) GenericLdapConfig(com.zimbra.cs.ldap.LdapServerConfig.GenericLdapConfig) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) ZSearchResultEnumeration(com.zimbra.cs.ldap.ZSearchResultEnumeration) ZAttributes(com.zimbra.cs.ldap.ZAttributes) LdapSizeLimitExceededException(com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException) ZSearchResultEntry(com.zimbra.cs.ldap.ZSearchResultEntry)

Aggregations

LdapSizeLimitExceededException (com.zimbra.cs.ldap.LdapException.LdapSizeLimitExceededException)9 ZLdapFilter (com.zimbra.cs.ldap.ZLdapFilter)6 SearchLdapOptions (com.zimbra.cs.ldap.SearchLdapOptions)5 ZLdapContext (com.zimbra.cs.ldap.ZLdapContext)5 ZSearchControls (com.zimbra.cs.ldap.ZSearchControls)4 ServiceException (com.zimbra.common.service.ServiceException)3 ZSearchResultEntry (com.zimbra.cs.ldap.ZSearchResultEntry)3 ZSearchResultEnumeration (com.zimbra.cs.ldap.ZSearchResultEnumeration)3 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)2 IAttributes (com.zimbra.cs.ldap.IAttributes)2 LdapInvalidAttrValueException (com.zimbra.cs.ldap.LdapException.LdapInvalidAttrValueException)2 Map (java.util.Map)2 LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)1 LdapException (com.zimbra.cs.ldap.LdapException)1 LdapContextNotEmptyException (com.zimbra.cs.ldap.LdapException.LdapContextNotEmptyException)1 LdapEntryAlreadyExistException (com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException)1 LdapEntryNotFoundException (com.zimbra.cs.ldap.LdapException.LdapEntryNotFoundException)1 LdapInvalidAttrNameException (com.zimbra.cs.ldap.LdapException.LdapInvalidAttrNameException)1 LdapInvalidSearchFilterException (com.zimbra.cs.ldap.LdapException.LdapInvalidSearchFilterException)1