Search in sources :

Example 56 with ZLdapContext

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

Example 57 with ZLdapContext

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);
    }
}
Also used : ZMutableEntry(com.zimbra.cs.ldap.ZMutableEntry) LdapEntryAlreadyExistException(com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Date(java.util.Date) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) CallbackContext(com.zimbra.cs.account.callback.CallbackContext) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain) LdapException(com.zimbra.cs.ldap.LdapException)

Example 58 with ZLdapContext

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);
}
Also used : ExternalLdapConfig(com.zimbra.cs.ldap.LdapServerConfig.ExternalLdapConfig) ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) ZSearchResultEntry(com.zimbra.cs.ldap.ZSearchResultEntry)

Example 59 with ZLdapContext

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;
}
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 60 with ZLdapContext

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);
    }
}
Also used : ZLdapContext(com.zimbra.cs.ldap.ZLdapContext) Server(com.zimbra.cs.account.Server) ServiceException(com.zimbra.common.service.ServiceException) Domain(com.zimbra.cs.account.Domain)

Aggregations

ZLdapContext (com.zimbra.cs.ldap.ZLdapContext)126 ServiceException (com.zimbra.common.service.ServiceException)65 AccountServiceException (com.zimbra.cs.account.AccountServiceException)62 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)60 LdapEntryAlreadyExistException (com.zimbra.cs.ldap.LdapException.LdapEntryAlreadyExistException)23 LdapException (com.zimbra.cs.ldap.LdapException)22 ZMutableEntry (com.zimbra.cs.ldap.ZMutableEntry)21 Domain (com.zimbra.cs.account.Domain)19 LdapEntry (com.zimbra.cs.account.ldap.entry.LdapEntry)18 CallbackContext (com.zimbra.cs.account.callback.CallbackContext)16 Date (java.util.Date)16 LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)14 HashMap (java.util.HashMap)14 SearchLdapOptions (com.zimbra.cs.ldap.SearchLdapOptions)13 ZLdapFilter (com.zimbra.cs.ldap.ZLdapFilter)12 Account (com.zimbra.cs.account.Account)11 LdapDynamicGroup (com.zimbra.cs.account.ldap.entry.LdapDynamicGroup)11 ZAttributes (com.zimbra.cs.ldap.ZAttributes)10 HashSet (java.util.HashSet)10 GuestAccount (com.zimbra.cs.account.GuestAccount)9