internal static void SetNewPasswordHashAndSaltForUser(SUserRow AUserDR, string ANewPassword, string AClientComputerName, string AClientIPAddress, TDBTransaction ATransaction) { byte[] Salt; int PwdSchemeVersionUpTillNow = AUserDR.PwdSchemeVersion; int CurrentPwdSchemeVersion = TPasswordHelper.CurrentPasswordSchemeNumber; EnsurePasswordHashingSchemeChangeIsAllowed(AUserDR.UserId, PwdSchemeVersionUpTillNow); // Note: In this Method we deliberately ignore the present value of the PwdSchemeVersion Column of AUserDR // because we *always* want to save the new password with the password hash of the current (=newest) version! // We always assign a new 'Salt' with every password change (best practice)! Salt = TPasswordHelper.CurrentPasswordScheme.GetNewPasswordSalt(); AUserDR.PasswordSalt = Convert.ToBase64String(Salt); AUserDR.PasswordHash = TUserManagerWebConnector.CreateHashOfPassword(ANewPassword, Convert.ToBase64String(Salt), CurrentPwdSchemeVersion); if (PwdSchemeVersionUpTillNow != CurrentPwdSchemeVersion) { // Ensure AUserDR.PwdSchemeVersion gets set to the current (=newest) version! AUserDR.PwdSchemeVersion = CurrentPwdSchemeVersion; TUserAccountActivityLog.AddUserAccountActivityLogEntry(AUserDR.UserId, TUserAccountActivityLog.USER_ACTIVITY_PWD_HASHING_SCHEME_UPGRADED, String.Format(Catalog.GetString( "The Password Scheme of User {0} got upgraded to {1}; previously it was {2}. "), AUserDR.UserId, TPasswordHelper.CurrentPasswordSchemeNumber, PwdSchemeVersionUpTillNow) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), ATransaction); } }
/// <summary> /// Save a failed user login attempt. If the number of permitted failed logins in a row gets exceeded then the /// user account gets Locked, too! /// </summary> /// <param name="AUserID">User ID.</param> /// <param name="UserDR">s_user DataRow of the user.</param> /// <param name="AClientComputerName">Name of the Client Computer that the authentication request came from.</param> /// <param name="AClientIPAddress">IP Address of the Client Computer that the authentication request came from.</param> /// <param name="ATransaction">Instantiated DB Transaction.</param> private static void SaveFailedLogin(string AUserID, SUserRow UserDR, string AClientComputerName, string AClientIPAddress, TDBTransaction ATransaction) { int AProcessID; int FailedLoginsUntilAccountGetsLocked = TSystemDefaults.GetInt32Default(SharedConstants.SYSDEFAULT_FAILEDLOGINS_UNTIL_ACCOUNT_GETS_LOCKED, 10); bool AccountLockedAtThisAttempt = false; // Console.WriteLine('PetraPrincipal.PetraIdentity.FailedLogins: ' + PetraPrincipal.PetraIdentity.FailedLogins.ToString + // '; PetraPrincipal.PetraIdentity.AccountLocked: ' + PetraPrincipal.PetraIdentity.AccountLocked.ToString); UserDR.FailedLogins++; UserDR.FailedLoginDate = DateTime.Now; UserDR.FailedLoginTime = Conversions.DateTimeToInt32Time(UserDR.FailedLoginDate.Value); // Check if User Account should be Locked due to too many successive failed log-in attempts if ((UserDR.FailedLogins >= FailedLoginsUntilAccountGetsLocked) && ((!UserDR.AccountLocked))) { // Lock User Account (this user will no longer be able to log in until a Sysadmin resets this flag!) UserDR.AccountLocked = true; AccountLockedAtThisAttempt = true; TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId, TUserAccountActivityLog.USER_ACTIVITY_PERMITTED_FAILED_LOGINS_EXCEEDED, String.Format(Catalog.GetString( "The permitted number of failed logins in a row got exceeded and the user account for the user {0} got locked! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), UserDR.UserId), ATransaction); } // Logging TLoginLog.AddLoginLogEntry(AUserID, AccountLockedAtThisAttempt ? TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_PWD_WRONG_ACCOUNT_GOT_LOCKED : TLoginLog.LOGIN_STATUS_TYPE_LOGIN_ATTEMPT_PWD_WRONG, String.Format(Catalog.GetString("User supplied wrong password{0}! (Failed Logins: now {1}; " + "Account Locked: now {2}, User Retired: {3}) "), (AccountLockedAtThisAttempt ? Catalog.GetString("; because the permitted number of failed logins in a row got exceeded the user account " + "for the user got locked! ") : String.Empty), UserDR.FailedLogins, UserDR.AccountLocked, UserDR.Retired) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), out AProcessID, ATransaction); SaveUser(AUserID, (SUserTable)UserDR.Table, ATransaction); }
public static bool SetUserPassword(string AUsername, string ANewPassword, bool APasswordNeedsChanged, bool AUnretireIfRetired, string AClientComputerName, string AClientIPAddress, out TVerificationResultCollection AVerification) { TVerificationResult VerificationResult; SUserTable UserTable; SUserRow UserDR; string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); bool BogusPasswordChangeAttempt = false; AVerification = new TVerificationResultCollection(); // Password quality check if (!TSharedSysManValidation.CheckPasswordQuality(ANewPassword, out VerificationResult)) { AVerification.Add(VerificationResult); return(false); } if (UserAuthenticationMethod == "OpenPetraDBSUser") { TDBTransaction SubmitChangesTransaction = null; bool SubmissionResult = false; TPetraPrincipal tempPrincipal; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { try { UserDR = TUserManagerWebConnector.LoadUser(AUsername.ToUpper(), out tempPrincipal, SubmitChangesTransaction); } catch (EUserNotExistantException) { // Because this cannot happen when a password change gets effected through normal OpenPetra // operation this is treated as a bogus operation that an attacker launches! BogusPasswordChangeAttempt = true; // Logging TUserAccountActivityLog.AddUserAccountActivityLogEntry(AUsername, TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_ATTEMPT_BY_SYSADMIN_FOR_NONEXISTING_USER, String.Format(Catalog.GetString( "A system administrator, {0}, made an attempt to change a User's password for UserID {1} " + "but that user doesn't exist! "), UserInfo.GUserInfo.UserID, AUsername) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); SubmissionResult = true; // Need to set this so that the DB Transaction gets committed! // Simulate that time is spent on 'authenticating' a user (although the user doesn't exist)...! Reason for that: see Method // SimulatePasswordAuthenticationForNonExistingUser! TUserManagerWebConnector.SimulatePasswordAuthenticationForNonExistingUser(); return; } UserTable = (SUserTable)UserDR.Table; // Note: We are on purpose NOT checking here whether the new password is the same as the existing // password (which would be done by calling the IsNewPasswordSameAsExistingPassword Method) because // if we would do that then the SYSADMIN could try to find out what the password of a user is by // seeing if (s)he would get a message that the new password must be different from the old password...! SetNewPasswordHashAndSaltForUser(UserDR, ANewPassword, AClientComputerName, AClientIPAddress, SubmitChangesTransaction); UserDR.PasswordNeedsChange = APasswordNeedsChanged; // 'Unretire' the user if the user has been previously 'retired' and also 'unlock' the User Account if // it has previously been locked if (AUnretireIfRetired) { UserDR.Retired = false; UserDR.AccountLocked = false; } try { SUserAccess.SubmitChanges(UserTable, SubmitChangesTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId, TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_BY_SYSADMIN, String.Format(Catalog.GetString( "The password of user {0} got changed by user {1} (the latter user has got SYSADMIN " + "privileges). "), UserDR.UserId, UserInfo.GUserInfo.UserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); } catch (Exception Exc) { TLogging.Log("An Exception occured during the saving of the new User Password by the SYSADMIN:" + Environment.NewLine + Exc.ToString()); throw; } SubmissionResult = true; }); return(!BogusPasswordChangeAttempt); } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return(auth.SetPassword(AUsername, ANewPassword)); } }
public static TSubmitChangesResult SaveSUser(ref MaintainUsersTDS ASubmitDS, string AClientComputerName, string AClientIPAddress) { TSubmitChangesResult ReturnValue = TSubmitChangesResult.scrError; TDBTransaction SubmitChangesTransaction = null; bool CanCreateUser; bool CanChangePassword; bool CanChangePermissions; int PwdSchemeVersionUpTillNow; int CurrentPwdSchemeVersion = TPasswordHelper.CurrentPasswordSchemeNumber; MaintainUsersTDS SubmitDS; SubmitDS = ASubmitDS; GetAuthenticationFunctionality(out CanCreateUser, out CanChangePassword, out CanChangePermissions); // make sure users are not deleted or added if this is not possible if (!CanCreateUser && (ASubmitDS.SUser != null)) { Int32 Counter = 0; while (Counter < ASubmitDS.SUser.Rows.Count) { if (ASubmitDS.SUser.Rows[Counter].RowState != DataRowState.Modified) { ASubmitDS.SUser.Rows.RemoveAt(Counter); } else { Counter++; } } } if (!CanChangePermissions && (ASubmitDS.SUserModuleAccessPermission != null)) { ASubmitDS.SUserModuleAccessPermission.Clear(); } // TODO: if user module access permissions have changed, automatically update the table access permissions? DBAccess.SimpleAutoTransactionWrapper(IsolationLevel.Serializable, "SaveSUser", out SubmitChangesTransaction, ref ReturnValue, delegate { if (SubmitDS.SUser != null) { foreach (SUserRow user in SubmitDS.SUser.Rows) { // for new users: create users on the alternative authentication method if (user.RowState == DataRowState.Added) { CreateUser(user.UserId, user.PasswordHash, user.FirstName, user.LastName, string.Empty, AClientComputerName, AClientIPAddress, SubmitChangesTransaction); user.AcceptChanges(); } else { PwdSchemeVersionUpTillNow = user.PwdSchemeVersion; // Has the 'Account Locked' state changed? if (Convert.ToBoolean(user[SUserTable.GetAccountLockedDBName(), DataRowVersion.Original]) != user.AccountLocked) { if (user.AccountLocked) { TUserAccountActivityLog.AddUserAccountActivityLogEntry(user.UserId, TUserAccountActivityLog.USER_ACTIVITY_USER_ACCOUNT_GOT_LOCKED, String.Format( StrUserChangedOtherUsersLockedState, UserInfo.GUserInfo.UserID, user.UserId, Catalog.GetString("locked")) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); } else { TUserAccountActivityLog.AddUserAccountActivityLogEntry(user.UserId, TUserAccountActivityLog.USER_ACTIVITY_USER_ACCOUNT_GOT_UNLOCKED, String.Format( StrUserChangedOtherUsersLockedState, UserInfo.GUserInfo.UserID, user.UserId, Catalog.GetString("unlocked")) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); // If the user account got locked when a Password Hashing Scheme was in place that isn't // the current one then require the user to change his/her password on next login. This is to // ensure that the Password Hash and Salt that gets placed in the s_user table record of this // user at his/her next logon isn't just the new Password Hash and Salt of the password that // the user had used when the user account got Locked (the Password Hashing Scheme of that user // will get upgraded to the current one then, but in case the system administrator locked the user // account because (s)he suspects a security breach then any future attempts to use the previous // password will be thwarted). if (PwdSchemeVersionUpTillNow != CurrentPwdSchemeVersion) { user.PasswordNeedsChange = true; } } } // Has the 'Retired' state changed? if (Convert.ToBoolean(user[SUserTable.GetRetiredDBName(), DataRowVersion.Original]) != user.Retired) { if (user.Retired) { TUserAccountActivityLog.AddUserAccountActivityLogEntry(user.UserId, TUserAccountActivityLog.USER_ACTIVITY_USER_GOT_RETIRED, String.Format( StrUserChangedOtherUsersRetiredState, UserInfo.GUserInfo.UserID, user.UserId, Catalog.GetString("retired")) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); } else { TUserAccountActivityLog.AddUserAccountActivityLogEntry(user.UserId, TUserAccountActivityLog.USER_ACTIVITY_USER_GOT_UNRETIRED, String.Format( StrUserChangedOtherUsersRetiredState, UserInfo.GUserInfo.UserID, user.UserId, Catalog.GetString("no longer retired")) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); // If the user account got retired when a Password Hashing Scheme was in place that isn't // the current one then require the user to change his/her password on next login. This is to // ensure that the Password Hash and Salt that gets placed in the s_user table record of this // user at his/her next logon isn't just the new Password Hash and Salt of the password that // the user had used when the user account got Retired (the Password Hashing Scheme of that user // will get upgraded to the current one then, but in case the system administrator retired the user // account because (s)he suspects a security breach then any future attempts to use the previous // password will be thwarted). if (PwdSchemeVersionUpTillNow != CurrentPwdSchemeVersion) { user.PasswordNeedsChange = true; } } } } } } try { MaintainUsersTDSAccess.SubmitChanges(SubmitDS, SubmitChangesTransaction.DataBaseObj); ReturnValue = TSubmitChangesResult.scrOK; } catch (Exception e) { TLogging.Log(e.Message); TLogging.Log(e.StackTrace); throw; } }); ASubmitDS = SubmitDS; return(ReturnValue); }
public static bool CreateUser(string AUsername, string APassword, string AFirstName, string AFamilyName, string AModulePermissions, string AClientComputerName, string AClientIPAddress, TDBTransaction ATransaction = null) { TDataBase DBConnectionObj = DBAccess.GetDBAccessObj(ATransaction); TDBTransaction ReadWriteTransaction = null; bool SeparateDBConnectionEstablished = false; bool NewTransaction; bool SubmissionOK = false; // TODO: check permissions. is the current user allowed to create other users? SUserTable userTable = new SUserTable(); SUserRow newUser = userTable.NewRowTyped(); newUser.UserId = AUsername; newUser.FirstName = AFirstName; newUser.LastName = AFamilyName; if (AUsername.Contains("@")) { newUser.EmailAddress = AUsername; newUser.UserId = AUsername.Substring(0, AUsername.IndexOf("@")). Replace(".", string.Empty). Replace("_", string.Empty).ToUpper(); } if (DBConnectionObj == null) { // ATransaction was null and GDBAccess is also null: we need to establish a DB Connection manually here! DBConnectionObj = DBAccess.SimpleEstablishDBConnection("CreateUser"); SeparateDBConnectionEstablished = true; } ReadWriteTransaction = DBConnectionObj.GetNewOrExistingTransaction( IsolationLevel.Serializable, out NewTransaction, "CreateUser"); try { // Check whether the user that we are asked to create already exists if (SUserAccess.Exists(newUser.UserId, ReadWriteTransaction)) { TLogging.Log("Cannot create new user because a user with User Name '" + newUser.UserId + "' already exists!"); return(false); } newUser.PwdSchemeVersion = TPasswordHelper.CurrentPasswordSchemeNumber; userTable.Rows.Add(newUser); string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); if (UserAuthenticationMethod == "OpenPetraDBSUser") { if (APassword.Length > 0) { SetNewPasswordHashAndSaltForUser(newUser, APassword, AClientComputerName, AClientIPAddress, ReadWriteTransaction); if (AModulePermissions != TMaintenanceWebConnector.DEMOMODULEPERMISSIONS) { newUser.PasswordNeedsChange = true; } } } else { try { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); if (!auth.CreateUser(AUsername, APassword, AFirstName, AFamilyName)) { newUser = null; } } catch (Exception e) { TLogging.Log("Problem loading user authentication method " + UserAuthenticationMethod + ": " + e.ToString()); return(false); } } if (newUser != null) { SUserAccess.SubmitChanges(userTable, ReadWriteTransaction); List <string> modules = new List <string>(); if (AModulePermissions == DEMOMODULEPERMISSIONS) { modules.Add("PTNRUSER"); modules.Add("FINANCE-1"); ALedgerTable theLedgers = ALedgerAccess.LoadAll(ReadWriteTransaction); foreach (ALedgerRow ledger in theLedgers.Rows) { modules.Add("LEDGER" + ledger.LedgerNumber.ToString("0000")); } } else { string[] modulePermissions = AModulePermissions.Split(new char[] { ',' }); foreach (string s in modulePermissions) { if (s.Trim().Length > 0) { modules.Add(s.Trim()); } } } SUserModuleAccessPermissionTable moduleAccessPermissionTable = new SUserModuleAccessPermissionTable(); foreach (string module in modules) { SUserModuleAccessPermissionRow moduleAccessPermissionRow = moduleAccessPermissionTable.NewRowTyped(); moduleAccessPermissionRow.UserId = newUser.UserId; moduleAccessPermissionRow.ModuleId = module; moduleAccessPermissionRow.CanAccess = true; moduleAccessPermissionTable.Rows.Add(moduleAccessPermissionRow); } SUserModuleAccessPermissionAccess.SubmitChanges(moduleAccessPermissionTable, ReadWriteTransaction); // TODO: table permissions should be set by the module list // TODO: add p_data_label... tables here so user can generally have access string[] tables = new string[] { "p_bank", "p_church", "p_family", "p_location", "p_organisation", "p_partner", "p_partner_location", "p_partner_type", "p_person", "p_unit", "p_venue", "p_data_label", "p_data_label_lookup", "p_data_label_lookup_category", "p_data_label_use", "p_data_label_value_partner", }; SUserTableAccessPermissionTable tableAccessPermissionTable = new SUserTableAccessPermissionTable(); foreach (string table in tables) { SUserTableAccessPermissionRow tableAccessPermissionRow = tableAccessPermissionTable.NewRowTyped(); tableAccessPermissionRow.UserId = newUser.UserId; tableAccessPermissionRow.TableName = table; tableAccessPermissionTable.Rows.Add(tableAccessPermissionRow); } SUserTableAccessPermissionAccess.SubmitChanges(tableAccessPermissionTable, ReadWriteTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(newUser.UserId, TUserAccountActivityLog.USER_ACTIVITY_USER_RECORD_CREATED, String.Format(Catalog.GetString("The user record for the new user {0} got created by user {1}. "), newUser.UserId, UserInfo.GUserInfo.UserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), ReadWriteTransaction); SubmissionOK = true; return(true); } } finally { if (NewTransaction) { if (SubmissionOK) { ReadWriteTransaction.DataBaseObj.CommitTransaction(); } else { ReadWriteTransaction.DataBaseObj.RollbackTransaction(); } if (SeparateDBConnectionEstablished) { DBConnectionObj.CloseDBConnection(); } } } return(false); }
public static bool SetUserPassword(string AUserID, string ANewPassword, string ACurrentPassword, bool APasswordNeedsChanged, string AClientComputerName, string AClientIPAddress, out TVerificationResultCollection AVerification) { string UserAuthenticationMethod = TAppSettingsManager.GetValue("UserAuthenticationMethod", "OpenPetraDBSUser", false); TVerificationResult VerificationResult; TVerificationResultCollection VerificationResultColl = null; SUserRow UserDR = null; SUserTable UserTable = null; bool BogusPasswordChangeAttempt = false; AVerification = new TVerificationResultCollection(); // Security check: Is the user that is performing the password change request the current user? if (AUserID != UserInfo.GUserInfo.UserID) { throw new EOPAppException( "The setting of a User's Password must only be done by the user itself, but this isn't the case here and therefore the request gets denied"); } // Password quality check if (!TSharedSysManValidation.CheckPasswordQuality(ANewPassword, out VerificationResult)) { AVerification.Add(VerificationResult); return(false); } if (UserAuthenticationMethod == "OpenPetraDBSUser") { TPetraPrincipal tempPrincipal; TDBTransaction SubmitChangesTransaction = null; bool SubmissionResult = false; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { try { UserDR = TUserManagerWebConnector.LoadUser(AUserID.ToUpper(), out tempPrincipal, SubmitChangesTransaction); } catch (EUserNotExistantException) { // Because this cannot happen when a password change gets effected through normal OpenPetra // operation this is treated as a bogus operation that an attacker launches! BogusPasswordChangeAttempt = true; // Logging TUserAccountActivityLog.AddUserAccountActivityLogEntry(AUserID, TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_ATTEMPT_BY_USER_FOR_NONEXISTING_USER, String.Format(Catalog.GetString( "User {0} tried to make an attempt to change a User's password for UserID {1} " + "but that user doesn't exist! "), UserInfo.GUserInfo.UserID, AUserID) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); SubmissionResult = true; // Need to set this so that the DB Transaction gets committed! // Simulate that time is spent on 'authenticating' a user (although the user doesn't exist)...! Reason for that: see Method // SimulatePasswordAuthenticationForNonExistingUser! TUserManagerWebConnector.SimulatePasswordAuthenticationForNonExistingUser(); return; } UserTable = (SUserTable)UserDR.Table; // Security check: Is the supplied current password correct? if (TUserManagerWebConnector.CreateHashOfPassword(ACurrentPassword, UserDR.PasswordSalt, UserDR.PwdSchemeVersion) != UserDR.PasswordHash) { VerificationResultColl = new TVerificationResultCollection(); VerificationResultColl.Add(new TVerificationResult("Password Verification", Catalog.GetString( "The current password was entered incorrectly! The password did not get changed."), TResultSeverity.Resv_Critical)); try { SUserAccess.SubmitChanges(UserTable, SubmitChangesTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId, TUserAccountActivityLog.USER_ACTIVITY_PWD_WRONG_WHILE_PWD_CHANGE, String.Format(Catalog.GetString( "User {0} supplied the wrong current password while attempting to change " + "his/her password! ") + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), UserInfo.GUserInfo.UserID), SubmitChangesTransaction); SubmissionResult = true; } catch (Exception Exc) { TLogging.Log(String.Format( "An Exception occured during the changing of the User Password by user '{0}' (Situation 1):", AUserID) + Environment.NewLine + Exc.ToString()); throw; } } }); if (BogusPasswordChangeAttempt) { // Note: VerificationResultColl will be null in this case because we don't want to disclose to an attackeer // why the password change attempt was denied!!! return(false); } if (VerificationResultColl != null) { AVerification = VerificationResultColl; return(false); } // Security check: Is the supplied new password the same than the current password? if (IsNewPasswordSameAsExistingPassword(ANewPassword, UserDR, out VerificationResult)) { AVerification.Add(VerificationResult); return(false); } // // All checks passed: We go aheand and change the user's password! // SetNewPasswordHashAndSaltForUser(UserDR, ANewPassword, AClientComputerName, AClientIPAddress, SubmitChangesTransaction); UserDR.PasswordNeedsChange = false; DBAccess.GDBAccessObj.BeginAutoTransaction(IsolationLevel.Serializable, ref SubmitChangesTransaction, ref SubmissionResult, delegate { try { SUserAccess.SubmitChanges(UserTable, SubmitChangesTransaction); TUserAccountActivityLog.AddUserAccountActivityLogEntry(UserDR.UserId, (APasswordNeedsChanged ? TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_BY_USER_ENFORCED : TUserAccountActivityLog.USER_ACTIVITY_PWD_CHANGE_BY_USER), String.Format(Catalog.GetString("User {0} changed his/her password{1}"), UserInfo.GUserInfo.UserID, (APasswordNeedsChanged ? Catalog.GetString(" (enforced password change.) ") : ". ")) + String.Format(ResourceTexts.StrRequestCallerInfo, AClientComputerName, AClientIPAddress), SubmitChangesTransaction); SubmissionResult = true; } catch (Exception Exc) { TLogging.Log(String.Format("An Exception occured during the changing of the User Password by user '{0}' (Situation 2):", AUserID) + Environment.NewLine + Exc.ToString()); throw; } }); return(true); } else { IUserAuthentication auth = TUserManagerWebConnector.LoadAuthAssembly(UserAuthenticationMethod); return(auth.SetPassword(AUserID, ANewPassword, ACurrentPassword)); } }