1
0
mirror of https://github.com/anope/anope.git synced 2026-06-26 11:16:38 +02:00

Fix various inconsistencies/crashes related to having multiple opers configured for the same user through combinations of os_oper/config/m_sql_oper

This commit is contained in:
Adam
2016-01-19 16:25:02 -05:00
parent 4771af1cb8
commit 164b349ef9
3 changed files with 43 additions and 10 deletions
+34 -10
View File
@@ -17,6 +17,18 @@ class SQLOperResult : public SQL::Interface
~SQLOperResultDeleter() { delete res; }
};
void Deoper()
{
if (user->Account() && user->Account()->o && dynamic_cast<SQLOper *>(user->Account()->o))
{
delete user->Account()->o;
user->Account()->o = NULL;
Log(this->owner) << "m_sql_oper: Removed services operator from " << user->nick << " (" << user->Account()->display << ")";
user->RemoveMode(OperServ, "OPER"); // Probably not set, just incase
}
}
public:
SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { }
@@ -24,9 +36,16 @@ class SQLOperResult : public SQL::Interface
{
SQLOperResultDeleter d(this);
if (!user || !user->Account() || r.Rows() == 0)
if (!user || !user->Account())
return;
if (r.Rows() == 0)
{
Log(LOG_DEBUG) << "m_sql_oper: Got 0 rows for " << user->nick;
Deoper();
return;
}
Anope::string opertype;
try
{
@@ -34,6 +53,7 @@ class SQLOperResult : public SQL::Interface
}
catch (const SQL::Exception &)
{
Log(this) << "Expected column named \"opertype\" but one was not found";
return;
}
@@ -44,19 +64,15 @@ class SQLOperResult : public SQL::Interface
{
modes = r.Get(0, "modes");
}
catch (const SQL::Exception &) { }
catch (const SQL::Exception &)
{
// Common case here is an exception, but this probably doesn't get this far often
}
BotInfo *OperServ = Config->GetClient("OperServ");
if (opertype.empty())
{
if (user->Account() && user->Account()->o && dynamic_cast<SQLOper *>(user->Account()->o))
{
delete user->Account()->o;
user->Account()->o = NULL;
Log(this->owner) << "m_sql_oper: Removed services operator from " << user->nick << " (" << user->Account()->display << ")";
user->RemoveMode(OperServ, "OPER"); // Probably not set, just incase
}
Deoper();
return;
}
@@ -67,9 +83,17 @@ class SQLOperResult : public SQL::Interface
return;
}
if (user->Account()->o && !dynamic_cast<SQLOper *>(user->Account()->o))
{
Log(this) << "Oper " << user->Account()->display << " has type " << opertype << ", but is already configured as an oper of type " << user->Account()->o->ot->GetName();
return;
}
if (!user->Account()->o || user->Account()->o->ot != ot)
{
Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype;
delete user->Account()->o;
user->Account()->o = new SQLOper(user->Account()->display, ot);
}