package org.ovirt.engine.core.bll; import java.util.Collections; import java.util.List; import java.util.Map; import org.ovirt.engine.core.bll.adbroker.AdActionType; import org.ovirt.engine.core.bll.adbroker.BrokerUtils; import org.ovirt.engine.core.bll.adbroker.LdapBroker; import org.ovirt.engine.core.bll.adbroker.LdapBrokerUtils; import org.ovirt.engine.core.bll.adbroker.LdapFactory; import org.ovirt.engine.core.bll.adbroker.LdapReturnValueBase; import org.ovirt.engine.core.bll.adbroker.LdapSearchByUserNameParameters; import org.ovirt.engine.core.bll.adbroker.UserAuthenticationResult; import org.ovirt.engine.core.bll.session.SessionDataContainer; import org.ovirt.engine.core.common.AuditLogType; import org.ovirt.engine.core.common.VdcObjectType; import org.ovirt.engine.core.common.action.LoginResult; import org.ovirt.engine.core.common.action.LoginUserParameters; import org.ovirt.engine.core.common.action.VdcLoginReturnValueBase; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.businessentities.AdUser; import org.ovirt.engine.core.common.config.Config; import org.ovirt.engine.core.common.config.ConfigValues; import org.ovirt.engine.core.common.users.VdcUser; import org.ovirt.engine.core.compat.Guid; import org.ovirt.engine.core.compat.LogCompat; import org.ovirt.engine.core.compat.LogFactoryCompat; import org.ovirt.engine.core.compat.RefObject; import org.ovirt.engine.core.compat.StringHelper; import org.ovirt.engine.core.dal.VdcBllMessages; import org.ovirt.engine.core.dal.dbbroker.DbFacade; import org.ovirt.engine.core.dal.dbbroker.user_sessions; import org.ovirt.engine.core.utils.threadpool.ThreadPoolUtil; public abstract class LoginBaseCommand<T extends LoginUserParameters> extends CommandBase<T> { public LoginBaseCommand(T parameters) { super(parameters); } @Override protected VdcReturnValueBase CreateReturnValue() { return new VdcLoginReturnValueBase(); } private void HandleAuthenticationError(List<VdcBllMessages> errorMessages) { // check if authentication failed due to password expiration LdapBroker adFactory = LdapFactory.getInstance(BrokerUtils.getLoginDomain(getParameters().getUserName(), getDomain())); if (adFactory == null) { addCanDoActionMessage(VdcBllMessages.USER_FAILED_TO_AUTHENTICATION_WRONG_AUTHENTICATION_METHOD); ((VdcLoginReturnValueBase) getReturnValue()).setLoginResult(LoginResult.CantAuthenticate); log.errorFormat(getReturnValue().getCanDoActionMessages().get(0) + " : {0}", getParameters().getUserName()); return; } VdcBllMessages canDoActionMessage = VdcBllMessages.USER_FAILED_TO_AUTHENTICATE; LoginResult result = LoginResult.CantAuthenticate; if (!Config.<String> GetValue(ConfigValues.AuthenticationMethod).toUpperCase().equals("LDAP")) { // In case we're using LDAP+GSSAPI/Kerberos - and there was an // authentication error - // we cannot query information about the user - we can do it only in // local user Object tempVar = null; Object execResult = adFactory.RunAdAction( AdActionType.GetAdUserByUserName, new LdapSearchByUserNameParameters(getParameters().getSessionId(), getDomain(), getParameters() .getUserName())); if (execResult != null) { LdapReturnValueBase adExecResult = (LdapReturnValueBase) execResult; tempVar = adExecResult.getReturnValue(); } AdUser user = (AdUser) ((tempVar instanceof AdUser) ? tempVar : null); if (user != null && user.getPasswordExpired()) { // If the password is expired - report just the error to the user errorMessages.clear(); errorMessages.add(VdcBllMessages.USER_PASSWORD_EXPIRED); result = LoginResult.PasswordExpired; } } // If for some reason the error messages list is still empty - add the general "user cant authenticate" message if (errorMessages.size() == 0) { errorMessages.add(VdcBllMessages.USER_FAILED_TO_AUTHENTICATE); } for (VdcBllMessages msg : errorMessages) { getReturnValue().getCanDoActionMessages().add(msg.name()); } ((VdcLoginReturnValueBase) getReturnValue()).setLoginResult(result); log.errorFormat(getReturnValue().getCanDoActionMessages().get(0) + " : {0}", getParameters().getUserName()); } /** * Handles the user session. * * @param adUser * The ad user. */ protected void HandleUserSession(AdUser adUser) { if (!StringHelper.isNullOrEmpty(getParameters().getHttpSessionId())) { user_sessions user_sessions = new user_sessions("", "", new java.util.Date(), "", getParameters() .getHttpSessionId(), adUser.getUserId()); DbFacade.getInstance().getDbUserDAO().saveSession(user_sessions); } } public String getUserPassword() { return getParameters().getUserPassword(); } public String getDomain() { return getParameters().getDomain(); } @Override public AuditLogType getAuditLogTypeValue() { return getSucceeded() ? AuditLogType.USER_VDC_LOGIN : AuditLogType.USER_VDC_LOGIN_FAILED; } protected abstract UserAuthenticationResult AuthenticateUser(RefObject<Boolean> isLocalBackend, RefObject<Boolean> isAdmin); protected AdUser _adUser; @Override protected void executeCommand() { // add user session // todo : insert correct values of all arguments, separate HandleUserSession(_adUser); setActionReturnValue(getCurrentUser()); ((VdcLoginReturnValueBase) getReturnValue()).setLoginResult(LoginResult.Autheticated); // Permissions for this user might been changed since last login so // update he's isAdmin flag accordingly updateUserData(); setSucceeded(true); } @Override protected boolean canDoAction() { boolean authenticated = false; VdcUser vdcUser = (VdcUser) SessionDataContainer.getInstance().GetData("VdcUser"); if (vdcUser == null) { // if (LicenseManager.LicenseManager.Instance == null || // LicenseManager.LicenseManager.Instance.LicenseSettings == null) // { // log.error("User Login: License manager illegal"); // ReturnValue.CanDoActionMessages.Add(VdcBllMessages.ERROR_LICENSE_ILLEGAL.toString()); // ((VdcLoginReturnValueBase)ReturnValue).LoginResult = // LoginResult.CantAuthenticate; // return false; // } // else if // (LicenseManager.LicenseManager.Instance.LicenseSettings.IsInNoLicenseState) // { // log.error("Licence Manager is in 'No-License' state"); // ReturnValue.CanDoActionMessages.Add(VdcBllMessages.ERROR_LICENSE_NO_LICENSE.toString()); // ((VdcLoginReturnValueBase)ReturnValue).LoginResult = // LoginResult.CantAuthenticate; // return false; // } // else { boolean domainFound = false; List<String> vdcDomains = LdapBrokerUtils.getDomainsList(); for (String domain : vdcDomains) { if (StringHelper.EqOp(domain.toLowerCase(), getDomain().toLowerCase())) { domainFound = true; break; } } if (!domainFound) { addCanDoActionMessage(VdcBllMessages.USER_CANNOT_LOGIN_DOMAIN_NOT_SUPPORTED); return false; } } boolean isLocalBackend = false; boolean isAdmin = false; RefObject<Boolean> tempRefObject2 = new RefObject<Boolean>(isLocalBackend); RefObject<Boolean> tempRefObject3 = new RefObject<Boolean>(isAdmin); UserAuthenticationResult result = AuthenticateUser(tempRefObject2, tempRefObject3); // If no result object is returned from authentication - create a result object with general authentication // error if (result == null) { result = new UserAuthenticationResult(VdcBllMessages.USER_FAILED_TO_AUTHENTICATE); } _adUser = result.getUser(); authenticated = result.isSuccessful(); isLocalBackend = tempRefObject2.argvalue; isAdmin = tempRefObject3.argvalue; if ((!authenticated || _adUser == null) && !isLocalBackend) { HandleAuthenticationError(result.getErrorMessages()); authenticated = false; } } else { addCanDoActionMessage(VdcBllMessages.USER_IS_ALREADY_LOGGED_IN); } // todo: temp because Current user is null until execute if (authenticated) { VdcUser currentUser = new VdcUser(_adUser); setCurrentUser(currentUser); if (!StringHelper.isNullOrEmpty(getParameters().getSessionId())) { SessionDataContainer.getInstance().SetData(getParameters().getSessionId(), "VdcUser", getCurrentUser()); // // if (SessionContainer.getInstance().GetData("VdcUser") == // null) // { // SessionContainer.getInstance().SetData("VdcUser",CurrentUser); // } } else if(!SessionDataContainer.getInstance().SetData("VdcUser", getCurrentUser())) { addCanDoActionMessage(VdcBllMessages.USER_CANNOT_LOGIN_SESSION_MISSING); authenticated = false; } //Persist the most updated version of the user, as received from AD, as this may //affect MLA later on if (authenticated) { authenticated = UserCommandBase.persistAuthenticatedUser(_adUser) != null; } } return authenticated; } private static LogCompat log = LogFactoryCompat.getLog(LoginBaseCommand.class); @Override protected boolean IsUserAutorizedToRunAction() { if (log.isDebugEnabled()) { log.debugFormat("IsUserAutorizedToRunAction: Login - no permission check"); } return true; } @Override public Map<Guid, VdcObjectType> getPermissionCheckSubjects() { // Not needed for admin operations. return Collections.emptyMap(); } private void updateUserData() { ThreadPoolUtil.execute(new Runnable() { @Override public void run() { DbFacade.getInstance().updateLastAdminCheckStatus(_adUser.getUserId()); // test what happends whern RTE is being thrown throw new RuntimeException("---- Test RT exception throwing fro login command by another thread ----"); } }); } }