Search in sources :

Example 1 with AuthMech

use of com.zimbra.cs.account.auth.AuthMechanism.AuthMech in project zm-mailbox by Zimbra.

the class LdapProvisioning method checkAuthConfig.

@Override
public Provisioning.Result checkAuthConfig(Map attrs, String name, String password) throws ServiceException {
    AuthMech mech = AuthMech.fromString(Check.getRequiredAttr(attrs, Provisioning.A_zimbraAuthMech));
    if (!(mech == AuthMech.ldap || mech == AuthMech.ad)) {
        throw ServiceException.INVALID_REQUEST("auth mech must be: " + AuthMech.ldap.name() + " or " + AuthMech.ad.name(), null);
    }
    String[] url = Check.getRequiredMultiAttr(attrs, Provisioning.A_zimbraAuthLdapURL);
    // TODO, need admin UI work for zimbraAuthLdapStartTlsEnabled
    String startTLSEnabled = (String) attrs.get(Provisioning.A_zimbraAuthLdapStartTlsEnabled);
    boolean requireStartTLS = startTLSEnabled == null ? false : ProvisioningConstants.TRUE.equals(startTLSEnabled);
    try {
        String searchFilter = (String) attrs.get(Provisioning.A_zimbraAuthLdapSearchFilter);
        if (searchFilter != null) {
            String searchPassword = (String) attrs.get(Provisioning.A_zimbraAuthLdapSearchBindPassword);
            String searchDn = (String) attrs.get(Provisioning.A_zimbraAuthLdapSearchBindDn);
            String searchBase = (String) attrs.get(Provisioning.A_zimbraAuthLdapSearchBase);
            if (searchBase == null)
                searchBase = "";
            searchFilter = LdapUtil.computeDn(name, searchFilter);
            if (ZimbraLog.account.isDebugEnabled())
                ZimbraLog.account.debug("auth with search filter of " + searchFilter);
            ldapAuthenticate(url, requireStartTLS, password, searchBase, searchFilter, searchDn, searchPassword);
            return new Provisioning.Result(Check.STATUS_OK, "", searchFilter);
        }
        String bindDn = (String) attrs.get(Provisioning.A_zimbraAuthLdapBindDn);
        if (bindDn != null) {
            String dn = LdapUtil.computeDn(name, bindDn);
            if (ZimbraLog.account.isDebugEnabled())
                ZimbraLog.account.debug("auth with bind dn template of " + dn);
            ldapAuthenticate(url, requireStartTLS, dn, password);
            return new Provisioning.Result(Check.STATUS_OK, "", dn);
        }
        throw ServiceException.INVALID_REQUEST("must specify " + Provisioning.A_zimbraAuthLdapSearchFilter + " or " + Provisioning.A_zimbraAuthLdapBindDn, null);
    } catch (ServiceException e) {
        return toResult(e, "");
    }
}
Also used : AuthMech(com.zimbra.cs.account.auth.AuthMechanism.AuthMech) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException)

Example 2 with AuthMech

use of com.zimbra.cs.account.auth.AuthMechanism.AuthMech in project zm-mailbox by Zimbra.

the class AutoProvisionLazy method auth.

private AutoProvAuthMech auth() {
    String authMechStr = domain.getAttr(Provisioning.A_zimbraAuthMech);
    AuthMech authMech = null;
    try {
        authMech = AuthMech.fromString(authMechStr);
    } catch (ServiceException e) {
        ZimbraLog.autoprov.debug("invalid auth mech " + authMechStr, e);
    }
    // only support external LDAP auth for now
    if (AuthMech.ldap == authMech || AuthMech.ad == authMech) {
        Map<String, Object> authCtxt = new HashMap<String, Object>();
        try {
            prov.externalLdapAuth(domain, authMech, loginName, loginPassword, authCtxt);
            return AutoProvAuthMech.LDAP;
        } catch (ServiceException e) {
            ZimbraLog.autoprov.info("unable to authenticate " + loginName + " for auto provisioning", e);
        }
    } else if (AuthMech.kerberos5 == authMech) {
        try {
            Krb5Login.verifyPassword(loginName, loginPassword);
            return AutoProvAuthMech.KRB5;
        } catch (LoginException e) {
            ZimbraLog.autoprov.info("unable to authenticate " + loginName + " for auto provisioning", e);
        }
    } else {
    // unsupported auth mechanism for lazy auto provision
    // Provisioning.AM_CUSTOM is not supported because the custom auth 
    // interface required a Zimrba Account instance.
    }
    return null;
}
Also used : AutoProvAuthMech(com.zimbra.common.account.ZAttrProvisioning.AutoProvAuthMech) AuthMech(com.zimbra.cs.account.auth.AuthMechanism.AuthMech) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) HashMap(java.util.HashMap) LoginException(javax.security.auth.login.LoginException)

Example 3 with AuthMech

use of com.zimbra.cs.account.auth.AuthMechanism.AuthMech in project zm-mailbox by Zimbra.

the class Auth method handle.

@Override
public Element handle(Element request, Map<String, Object> context) throws ServiceException {
    ZimbraSoapContext zsc = getZimbraSoapContext(context);
    AuthToken at = null;
    Account acct = null;
    Provisioning prov = Provisioning.getInstance();
    boolean csrfSupport = request.getAttributeBool(AccountConstants.A_CSRF_SUPPORT, false);
    String name = request.getAttribute(AdminConstants.E_NAME, null);
    Element acctEl = request.getOptionalElement(AccountConstants.E_ACCOUNT);
    //only perform auth-token authentication if other credentials are not provided
    if (name == null && acctEl == null) {
        //get an auth token from cookie
        at = zsc.getAuthToken();
        if (at == null) {
            //if auth token is not in the cookie check for auth token in SOAP
            Element authTokenEl = request.getOptionalElement(AdminConstants.E_AUTH_TOKEN);
            if (authTokenEl != null) {
                try {
                    at = AuthProvider.getAuthToken(request, new HashMap<String, Object>());
                } catch (AuthTokenException e) {
                    throw ServiceException.AUTH_REQUIRED();
                }
            }
        }
        if (at == null) {
            //neither login credentials nor valid auth token could be retrieved
            throw ServiceException.AUTH_REQUIRED();
        }
        com.zimbra.cs.service.account.Auth.addAccountToLogContextByAuthToken(prov, at);
        if (at.isExpired())
            throw ServiceException.AUTH_EXPIRED();
        if (!at.isRegistered())
            throw ServiceException.AUTH_EXPIRED("authtoken is invalid");
        // make sure that the authenticated account is active and has not been deleted/disabled since the last request
        acct = prov.get(AccountBy.id, at.getAccountId(), at);
        if (acct == null || !acct.getAccountStatus(prov).equals(Provisioning.ACCOUNT_STATUS_ACTIVE))
            throw ServiceException.AUTH_EXPIRED();
        // make sure the authenticated account is an admin account
        checkAdmin(acct);
    } else {
        /*
             * only one of
             *     <name>...</name>
             * or
             *     <account by="name|id|foreignPrincipal">...</account>
             * can/must be specified
             */
        if (name != null && acctEl != null)
            throw ServiceException.INVALID_REQUEST("only one of <name> or <account> can be specified", null);
        if (name == null && acctEl == null)
            throw ServiceException.INVALID_REQUEST("missing <name> or <account>", null);
        String password = request.getAttribute(AdminConstants.E_PASSWORD);
        String twoFactorCode = request.getAttribute(AccountConstants.E_TWO_FACTOR_CODE, null);
        Element virtualHostEl = request.getOptionalElement(AccountConstants.E_VIRTUAL_HOST);
        String virtualHost = virtualHostEl == null ? null : virtualHostEl.getText().toLowerCase();
        String valuePassedIn;
        AccountBy by;
        String value;
        if (name != null) {
            valuePassedIn = name;
            by = AccountBy.name;
        } else {
            valuePassedIn = acctEl.getText();
            String byStr = acctEl.getAttribute(AccountConstants.A_BY, AccountBy.name.name());
            by = AccountBy.fromString(byStr);
        }
        value = valuePassedIn;
        try {
            if (by == AccountBy.name && value.indexOf("@") == -1) {
                // first try to get by adminName, which resolves the account under cn=admins,cn=zimbra
                // and does not need a domain
                acct = prov.get(AccountBy.adminName, value, zsc.getAuthToken());
                // not found, try applying virtual host name
                if (acct == null) {
                    if (virtualHost != null) {
                        Domain d = prov.get(Key.DomainBy.virtualHostname, virtualHost);
                        if (d != null)
                            value = value + "@" + d.getName();
                    }
                }
            }
            if (acct == null)
                acct = prov.get(by, value);
            if (acct == null)
                throw AuthFailedServiceException.AUTH_FAILED(value, valuePassedIn, "account not found");
            AccountUtil.addAccountToLogContext(prov, acct.getId(), ZimbraLog.C_NAME, ZimbraLog.C_ID, null);
            ZimbraLog.security.info(ZimbraLog.encodeAttrs(new String[] { "cmd", "AdminAuth", "account", value }));
            Map<String, Object> authCtxt = new HashMap<String, Object>();
            authCtxt.put(AuthContext.AC_ORIGINATING_CLIENT_IP, context.get(SoapEngine.ORIG_REQUEST_IP));
            authCtxt.put(AuthContext.AC_REMOTE_IP, context.get(SoapEngine.SOAP_REQUEST_IP));
            authCtxt.put(AuthContext.AC_ACCOUNT_NAME_PASSEDIN, valuePassedIn);
            authCtxt.put(AuthContext.AC_USER_AGENT, zsc.getUserAgent());
            authCtxt.put(AuthContext.AC_AS_ADMIN, Boolean.TRUE);
            prov.authAccount(acct, password, AuthContext.Protocol.soap, authCtxt);
            TwoFactorAuth twoFactorAuth = TwoFactorAuth.getFactory().getTwoFactorAuth(acct);
            boolean usingTwoFactorAuth = twoFactorAuth.twoFactorAuthEnabled();
            if (usingTwoFactorAuth) {
                if (twoFactorCode != null) {
                    twoFactorAuth.authenticate(twoFactorCode);
                }
            }
            checkAdmin(acct);
            AuthMech authedByMech = (AuthMech) authCtxt.get(AuthContext.AC_AUTHED_BY_MECH);
            at = AuthProvider.getAuthToken(acct, true, authedByMech);
        } catch (ServiceException se) {
            ZimbraLog.security.warn(ZimbraLog.encodeAttrs(new String[] { "cmd", "AdminAuth", "account", value, "error", se.getMessage() }));
            throw se;
        }
    }
    if (at != null) {
        at.setCsrfTokenEnabled(csrfSupport);
    }
    ServletRequest httpReq = (ServletRequest) context.get(SoapServlet.SERVLET_REQUEST);
    httpReq.setAttribute(CsrfFilter.AUTH_TOKEN, at);
    return doResponse(request, at, zsc, context, acct, csrfSupport);
}
Also used : Account(com.zimbra.cs.account.Account) HttpServletRequest(javax.servlet.http.HttpServletRequest) ServletRequest(javax.servlet.ServletRequest) HashMap(java.util.HashMap) Element(com.zimbra.common.soap.Element) Provisioning(com.zimbra.cs.account.Provisioning) AccountBy(com.zimbra.common.account.Key.AccountBy) AuthMech(com.zimbra.cs.account.auth.AuthMechanism.AuthMech) ServiceException(com.zimbra.common.service.ServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ZimbraSoapContext(com.zimbra.soap.ZimbraSoapContext) TwoFactorAuth(com.zimbra.cs.account.auth.twofactor.TwoFactorAuth) AuthTokenException(com.zimbra.cs.account.AuthTokenException) AuthToken(com.zimbra.cs.account.AuthToken) Domain(com.zimbra.cs.account.Domain)

Example 4 with AuthMech

use of com.zimbra.cs.account.auth.AuthMechanism.AuthMech in project zm-mailbox by Zimbra.

the class LdapProvisioning method verifyPasswordInternal.

/*
     * authAccount does all the status/mustChange checks, this just takes the
     * password and auths the user
     */
private void verifyPasswordInternal(Account acct, String password, AuthMechanism authMech, Map<String, Object> context) throws ServiceException {
    Domain domain = Provisioning.getInstance().getDomain(acct);
    boolean allowFallback = true;
    if (!authMech.isZimbraAuth()) {
        allowFallback = domain.getBooleanAttr(Provisioning.A_zimbraAuthFallbackToLocal, false) || acct.getBooleanAttr(Provisioning.A_zimbraIsAdminAccount, false) || acct.getBooleanAttr(Provisioning.A_zimbraIsDomainAdminAccount, false);
    }
    try {
        authMech.doAuth(this, domain, acct, password, context);
        AuthMech authedByMech = authMech.getMechanism();
        // context.put(AuthContext.AC_AUTHED_BY_MECH, authedByMech); TODO
        return;
    } catch (ServiceException e) {
        if (!allowFallback || authMech.isZimbraAuth())
            throw e;
        ZimbraLog.account.warn(authMech.getMechanism() + " auth for domain " + domain.getName() + " failed, fall back to zimbra default auth mechanism", e);
    }
    // fall back to zimbra default auth
    AuthMechanism.doZimbraAuth(this, domain, acct, password, context);
// context.put(AuthContext.AC_AUTHED_BY_MECH, Provisioning.AM_ZIMBRA); // TODO
}
Also used : AuthMech(com.zimbra.cs.account.auth.AuthMechanism.AuthMech) AccountServiceException(com.zimbra.cs.account.AccountServiceException) AuthFailedServiceException(com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException) ServiceException(com.zimbra.common.service.ServiceException) LdapDomain(com.zimbra.cs.account.ldap.entry.LdapDomain) Domain(com.zimbra.cs.account.Domain)

Aggregations

ServiceException (com.zimbra.common.service.ServiceException)4 AuthFailedServiceException (com.zimbra.cs.account.AccountServiceException.AuthFailedServiceException)4 AuthMech (com.zimbra.cs.account.auth.AuthMechanism.AuthMech)4 AccountServiceException (com.zimbra.cs.account.AccountServiceException)2 Domain (com.zimbra.cs.account.Domain)2 HashMap (java.util.HashMap)2 AccountBy (com.zimbra.common.account.Key.AccountBy)1 AutoProvAuthMech (com.zimbra.common.account.ZAttrProvisioning.AutoProvAuthMech)1 Element (com.zimbra.common.soap.Element)1 Account (com.zimbra.cs.account.Account)1 AuthToken (com.zimbra.cs.account.AuthToken)1 AuthTokenException (com.zimbra.cs.account.AuthTokenException)1 Provisioning (com.zimbra.cs.account.Provisioning)1 TwoFactorAuth (com.zimbra.cs.account.auth.twofactor.TwoFactorAuth)1 LdapDomain (com.zimbra.cs.account.ldap.entry.LdapDomain)1 ZimbraSoapContext (com.zimbra.soap.ZimbraSoapContext)1 LoginException (javax.security.auth.login.LoginException)1 ServletRequest (javax.servlet.ServletRequest)1 HttpServletRequest (javax.servlet.http.HttpServletRequest)1