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, "");
}
}
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;
}
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);
}
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
}
Aggregations