anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
m_sql_oper.cpp (4203B)
1 /* 2 * 3 * (C) 2012-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 */ 8 9 #include "module.h" 10 #include "modules/sql.h" 11 12 struct SQLOper : Oper 13 { 14 SQLOper(const Anope::string &n, OperType *o) : Oper(n, o) { } 15 }; 16 17 class SQLOperResult : public SQL::Interface 18 { 19 Reference<User> user; 20 21 struct SQLOperResultDeleter 22 { 23 SQLOperResult *res; 24 SQLOperResultDeleter(SQLOperResult *r) : res(r) { } 25 ~SQLOperResultDeleter() { delete res; } 26 }; 27 28 void Deoper() 29 { 30 if (user->Account() && user->Account()->o && dynamic_cast<SQLOper *>(user->Account()->o)) 31 { 32 delete user->Account()->o; 33 user->Account()->o = NULL; 34 35 Log(this->owner) << "m_sql_oper: Removed services operator from " << user->nick << " (" << user->Account()->display << ")"; 36 37 BotInfo *OperServ = Config->GetClient("OperServ"); 38 user->RemoveMode(OperServ, "OPER"); // Probably not set, just incase 39 } 40 } 41 42 public: 43 SQLOperResult(Module *m, User *u) : SQL::Interface(m), user(u) { } 44 45 void OnResult(const SQL::Result &r) anope_override 46 { 47 SQLOperResultDeleter d(this); 48 49 if (!user || !user->Account()) 50 return; 51 52 if (r.Rows() == 0) 53 { 54 Log(LOG_DEBUG) << "m_sql_oper: Got 0 rows for " << user->nick; 55 Deoper(); 56 return; 57 } 58 59 Anope::string opertype; 60 try 61 { 62 opertype = r.Get(0, "opertype"); 63 } 64 catch (const SQL::Exception &) 65 { 66 Log(this->owner) << "Expected column named \"opertype\" but one was not found"; 67 return; 68 } 69 70 Log(LOG_DEBUG) << "m_sql_oper: Got result for " << user->nick << ", opertype " << opertype; 71 72 Anope::string modes; 73 try 74 { 75 modes = r.Get(0, "modes"); 76 } 77 catch (const SQL::Exception &) 78 { 79 // Common case here is an exception, but this probably doesn't get this far often 80 } 81 82 BotInfo *OperServ = Config->GetClient("OperServ"); 83 if (opertype.empty()) 84 { 85 Deoper(); 86 return; 87 } 88 89 OperType *ot = OperType::Find(opertype); 90 if (ot == NULL) 91 { 92 Log(this->owner) << "m_sql_oper: Oper " << user->nick << " has type " << opertype << ", but this opertype does not exist?"; 93 return; 94 } 95 96 if (user->Account()->o && !dynamic_cast<SQLOper *>(user->Account()->o)) 97 { 98 Log(this->owner) << "Oper " << user->Account()->display << " has type " << opertype << ", but is already configured as an oper of type " << user->Account()->o->ot->GetName(); 99 return; 100 } 101 102 if (!user->Account()->o || user->Account()->o->ot != ot) 103 { 104 Log(this->owner) << "m_sql_oper: Tieing oper " << user->nick << " to type " << opertype; 105 106 delete user->Account()->o; 107 user->Account()->o = new SQLOper(user->Account()->display, ot); 108 } 109 110 if (!user->HasMode("OPER")) 111 { 112 IRCD->SendOper(user); 113 114 if (!modes.empty()) 115 user->SetModes(OperServ, "%s", modes.c_str()); 116 } 117 } 118 119 void OnError(const SQL::Result &r) anope_override 120 { 121 SQLOperResultDeleter d(this); 122 Log(this->owner) << "m_sql_oper: Error executing query " << r.GetQuery().query << ": " << r.GetError(); 123 } 124 }; 125 126 class ModuleSQLOper : public Module 127 { 128 Anope::string engine; 129 Anope::string query; 130 131 ServiceReference<SQL::Provider> SQL; 132 133 public: 134 ModuleSQLOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, EXTRA | VENDOR) 135 { 136 } 137 138 ~ModuleSQLOper() 139 { 140 for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it) 141 { 142 NickCore *nc = it->second; 143 144 if (nc->o && dynamic_cast<SQLOper *>(nc->o)) 145 { 146 delete nc->o; 147 nc->o = NULL; 148 } 149 } 150 } 151 152 void OnReload(Configuration::Conf *conf) anope_override 153 { 154 Configuration::Block *config = conf->GetModule(this); 155 156 this->engine = config->Get<const Anope::string>("engine"); 157 this->query = config->Get<const Anope::string>("query"); 158 159 this->SQL = ServiceReference<SQL::Provider>("SQL::Provider", this->engine); 160 } 161 162 void OnNickIdentify(User *u) anope_override 163 { 164 if (!this->SQL) 165 { 166 Log() << "Unable to find SQL engine"; 167 return; 168 } 169 170 SQL::Query q(this->query); 171 q.SetValue("a", u->Account()->display); 172 q.SetValue("i", u->ip.addr()); 173 174 this->SQL->Run(new SQLOperResult(this, u), q); 175 176 Log(LOG_DEBUG) << "m_sql_oper: Checking authentication for " << u->Account()->display; 177 } 178 }; 179 180 MODULE_INIT(ModuleSQLOper)