Add the ability for gods to impersonate users. For this, bit 6 needs to be

set in the target's UserFlags and the impersonator must have UserLevel 200
or above. The user can then log in using the target's name and their own
password.
avinationmerge
Melanie 2010-11-25 20:34:55 +01:00
parent c14592d4ba
commit ee9aca9c52
16 changed files with 138 additions and 8 deletions

View File

@ -50,5 +50,6 @@ namespace OpenSim.Data
bool Store(UserAccountData data);
bool Delete(string field, string val);
UserAccountData[] GetUsers(UUID scopeID, string query);
UserAccountData[] GetUsersWhere(UUID scopeID, string where);
}
}

View File

@ -238,5 +238,10 @@ namespace OpenSim.Data.MSSQL
return DoQuery(cmd);
}
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@ -80,5 +80,20 @@ namespace OpenSim.Data.MySQL
return DoQuery(cmd);
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
MySqlCommand cmd = new MySqlCommand();
if (scopeID != UUID.Zero)
{
where = "(ScopeID=?ScopeID or ScopeID='00000000-0000-0000-0000-000000000000') and (" + where + ")";
cmd.Parameters.AddWithValue("?ScopeID", scopeID.ToString());
}
cmd.CommandText = String.Format("select * from {0} where " + where, m_Realm);
return DoQuery(cmd);
}
}
}

View File

@ -156,5 +156,10 @@ namespace OpenSim.Data.Null
return false;
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@ -81,5 +81,10 @@ namespace OpenSim.Data.SQLite
return DoQuery(cmd);
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@ -77,5 +77,10 @@ namespace OpenSim.Data.SQLiteLegacy
return DoQuery(cmd);
}
public UserAccountData[] GetUsersWhere(UUID scopeID, string where)
{
return null;
}
}
}

View File

@ -172,6 +172,11 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts
return m_UserService.GetUserAccount(scopeID, Email);
}
public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query)
{
return null;
}
public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
{
return m_UserService.GetUserAccounts(scopeID, query);

View File

@ -31,6 +31,8 @@ using log4net;
using Nini.Config;
using System.Reflection;
using OpenSim.Services.Base;
using OpenSim.Server.Base;
using OpenSim.Services.Interfaces;
using OpenSim.Data;
using OpenSim.Framework;
@ -49,6 +51,12 @@ namespace OpenSim.Services.AuthenticationService
MethodBase.GetCurrentMethod().DeclaringType);
protected IAuthenticationData m_Database;
protected IUserAccountService m_UserAccountService = null;
public AuthenticationServiceBase(IConfigSource config, IUserAccountService acct) : this(config)
{
m_UserAccountService = acct;
}
public AuthenticationServiceBase(IConfigSource config) : base(config)
{

View File

@ -51,6 +51,12 @@ namespace OpenSim.Services.AuthenticationService
LogManager.GetLogger(
MethodBase.GetCurrentMethod().DeclaringType);
public PasswordAuthenticationService(IConfigSource config, IUserAccountService userService) :
base(config, userService)
{
m_log.Debug("[AUTH SERVICE]: Started with User Account access");
}
public PasswordAuthenticationService(IConfigSource config) :
base(config)
{
@ -58,28 +64,70 @@ namespace OpenSim.Services.AuthenticationService
public string Authenticate(UUID principalID, string password, int lifetime)
{
m_log.DebugFormat("[AUTH SERVICE]: Authenticating for {0}, user account service present: {1}", principalID, m_UserAccountService != null);
AuthenticationData data = m_Database.Get(principalID);
UserAccount user = null;
if (m_UserAccountService != null)
user = m_UserAccountService.GetUserAccount(UUID.Zero, principalID);
if (data != null && data.Data != null)
if (data == null || data.Data == null)
{
if (!data.Data.ContainsKey("passwordHash") ||
m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID);
return String.Empty;
}
if (!data.Data.ContainsKey("passwordHash") ||
!data.Data.ContainsKey("passwordSalt"))
{
return String.Empty;
}
string hashed = Util.Md5Hash(password + ":" +
data.Data["passwordSalt"].ToString());
m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString());
if (data.Data["passwordHash"].ToString() == hashed)
{
return GetToken(principalID, lifetime);
}
if (user == null)
{
m_log.DebugFormat("[PASS AUTH]: No user record for {0}", principalID);
return String.Empty;
}
int impersonateFlag = 1 << 6;
if ((user.UserFlags & impersonateFlag) == 0)
return String.Empty;
List<UserAccount> accounts = m_UserAccountService.GetUserAccountsWhere(UUID.Zero, "UserLevel >= 200");
if (accounts == null || accounts.Count == 0)
return String.Empty;
foreach (UserAccount a in accounts)
{
data = m_Database.Get(a.PrincipalID);
if (data == null || data.Data == null ||
!data.Data.ContainsKey("passwordHash") ||
!data.Data.ContainsKey("passwordSalt"))
{
return String.Empty;
continue;
}
string hashed = Util.Md5Hash(password + ":" +
hashed = Util.Md5Hash(password + ":" +
data.Data["passwordSalt"].ToString());
m_log.DebugFormat("[PASS AUTH]: got {0}; hashed = {1}; stored = {2}", password, hashed, data.Data["passwordHash"].ToString());
if (data.Data["passwordHash"].ToString() == hashed)
{
m_log.DebugFormat("[PASS AUTH]: {0} {1} impersonating {2}, proceeding with login", a.FirstName, a.LastName, principalID);
return GetToken(principalID, lifetime);
}
}
m_log.DebugFormat("[AUTH SERVICE]: PrincipalID {0} or its data not found", principalID);
m_log.DebugFormat("[PASS AUTH]: Impersonation of {0} failed", principalID);
return String.Empty;
}
}

View File

@ -47,6 +47,11 @@ namespace OpenSim.Services.AuthenticationService
// LogManager.GetLogger(
// MethodBase.GetCurrentMethod().DeclaringType);
public WebkeyAuthenticationService(IConfigSource config, IUserAccountService userService) :
base(config, userService)
{
}
public WebkeyAuthenticationService(IConfigSource config) :
base(config)
{

View File

@ -191,6 +191,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
return accounts;
}
public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string query)
{
return null;
}
public bool StoreUserAccount(UserAccount data)
{
m_log.InfoFormat("[SIMIAN ACCOUNT CONNECTOR]: Storing user account for " + data.Name);

View File

@ -187,6 +187,11 @@ namespace OpenSim.Services.Connectors
return accounts;
}
public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where)
{
return null; // Not implemented for regions
}
public virtual bool StoreUserAccount(UserAccount data)
{
Dictionary<string, object> sendData = new Dictionary<string, object>();

View File

@ -150,6 +150,7 @@ namespace OpenSim.Services.Interfaces
/// <param name="query"></param>
/// <returns></returns>
List<UserAccount> GetUserAccounts(UUID scopeID, string query);
List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where);
/// <summary>
/// Store the data given, wich replaces the stored data, therefore must be complete.

View File

@ -113,7 +113,8 @@ namespace OpenSim.Services.LLLoginService
Object[] args = new Object[] { config };
m_UserAccountService = ServerUtils.LoadPlugin<IUserAccountService>(accountService, args);
m_GridUserService = ServerUtils.LoadPlugin<IGridUserService>(gridUserService, args);
m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, args);
Object[] authArgs = new Object[] { config, m_UserAccountService };
m_AuthenticationService = ServerUtils.LoadPlugin<IAuthenticationService>(authService, authArgs);
m_InventoryService = ServerUtils.LoadPlugin<IInventoryService>(invService, args);
if (gridService != string.Empty)

View File

@ -282,6 +282,21 @@ namespace OpenSim.Services.UserAccountService
return ret;
}
public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where)
{
UserAccountData[] d = m_Database.GetUsersWhere(scopeID, where);
if (d == null)
return new List<UserAccount>();
List<UserAccount> ret = new List<UserAccount>();
foreach (UserAccountData data in d)
ret.Add(MakeUserAccount(data));
return ret;
}
#endregion
#region Console commands

View File

@ -1091,6 +1091,7 @@
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Services.Base"/>
<Reference name="OpenSim.Server.Base"/>
<Reference name="OpenSim.Services.Connectors"/>
<Reference name="OpenSim.Data"/>
<Reference name="Nini" path="../../../bin/"/>