anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
os_oper.cpp (8155B)
1 /* OperServ core functions 2 * 3 * (C) 2003-2022 Anope Team 4 * Contact us at team@anope.org 5 * 6 * Please read COPYING and README for further details. 7 * 8 * Based on the original code of Epona by Lara. 9 * Based on the original code of Services by Andy Church. 10 */ 11 12 #include "module.h" 13 14 struct MyOper : Oper, Serializable 15 { 16 MyOper(const Anope::string &n, OperType *o) : Oper(n, o), Serializable("Oper") { } 17 18 void Serialize(Serialize::Data &data) const anope_override 19 { 20 data["name"] << this->name; 21 data["type"] << this->ot->GetName(); 22 } 23 24 static Serializable* Unserialize(Serializable *obj, Serialize::Data &data) 25 { 26 Anope::string stype, sname; 27 28 data["type"] >> stype; 29 data["name"] >> sname; 30 31 OperType *ot = OperType::Find(stype); 32 if (ot == NULL) 33 return NULL; 34 NickCore *nc = NickCore::Find(sname); 35 if (nc == NULL) 36 return NULL; 37 38 MyOper *myo; 39 if (obj) 40 myo = anope_dynamic_static_cast<MyOper *>(obj); 41 else 42 myo = new MyOper(nc->display, ot); 43 nc->o = myo; 44 Log(LOG_NORMAL, "operserv/oper") << "Tied oper " << nc->display << " to type " << ot->GetName(); 45 return myo; 46 } 47 }; 48 49 class CommandOSOper : public Command 50 { 51 bool HasPrivs(CommandSource &source, OperType *ot) const 52 { 53 std::list<Anope::string> commands = ot->GetCommands(), privs = ot->GetPrivs(); 54 55 for (std::list<Anope::string>::iterator it = commands.begin(); it != commands.end(); ++it) 56 if (!source.HasCommand(*it)) 57 return false; 58 59 for (std::list<Anope::string>::iterator it = privs.begin(); it != privs.end(); ++it) 60 if (!source.HasPriv(*it)) 61 return false; 62 63 return true; 64 } 65 66 public: 67 CommandOSOper(Module *creator) : Command(creator, "operserv/oper", 1, 3) 68 { 69 this->SetDesc(_("View and change Services Operators")); 70 this->SetSyntax(_("ADD \037oper\037 \037type\037")); 71 this->SetSyntax(_("DEL \037oper\037")); 72 this->SetSyntax(_("INFO [\037type\037]")); 73 this->SetSyntax("LIST"); 74 } 75 76 void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) anope_override 77 { 78 const Anope::string &subcommand = params[0]; 79 80 if (subcommand.equals_ci("ADD") && params.size() > 2) 81 { 82 const Anope::string &oper = params[1]; 83 const Anope::string &otype = params[2]; 84 85 if (!source.HasPriv("operserv/oper/modify")) 86 { 87 source.Reply(ACCESS_DENIED); 88 return; 89 } 90 91 const NickAlias *na = NickAlias::Find(oper); 92 if (na == NULL) 93 source.Reply(NICK_X_NOT_REGISTERED, oper.c_str()); 94 else if (na->nc->o) 95 source.Reply(_("Nick \002%s\002 is already an operator."), na->nick.c_str()); 96 else 97 { 98 OperType *ot = OperType::Find(otype); 99 if (ot == NULL) 100 { 101 source.Reply(_("Oper type \002%s\002 has not been configured."), otype.c_str()); 102 return; 103 } 104 105 if (!HasPrivs(source, ot)) 106 { 107 source.Reply(ACCESS_DENIED); 108 return; 109 } 110 111 na->nc->o = new MyOper(na->nc->display, ot); 112 113 if (Anope::ReadOnly) 114 source.Reply(READ_ONLY_MODE); 115 116 Log(LOG_ADMIN, source, this) << "ADD " << na->nick << " as type " << ot->GetName(); 117 source.Reply("%s (%s) added to the \002%s\002 list.", na->nick.c_str(), na->nc->display.c_str(), ot->GetName().c_str()); 118 } 119 } 120 else if (subcommand.equals_ci("DEL") && params.size() > 1) 121 { 122 const Anope::string &oper = params[1]; 123 124 if (!source.HasPriv("operserv/oper/modify")) 125 { 126 source.Reply(ACCESS_DENIED); 127 return; 128 } 129 130 const NickAlias *na = NickAlias::Find(oper); 131 if (na == NULL) 132 source.Reply(NICK_X_NOT_REGISTERED, oper.c_str()); 133 else if (!na->nc || !na->nc->o) 134 source.Reply(_("Nick \002%s\002 is not a Services Operator."), oper.c_str()); 135 else if (!HasPrivs(source, na->nc->o->ot)) 136 source.Reply(ACCESS_DENIED); 137 else if (std::find(Config->Opers.begin(), Config->Opers.end(), na->nc->o) != Config->Opers.end()) 138 source.Reply(_("Oper \002%s\002 is configured in the configuration file(s) and can not be removed by this command."), na->nc->display.c_str()); 139 else 140 { 141 delete na->nc->o; 142 na->nc->o = NULL; 143 144 if (Anope::ReadOnly) 145 source.Reply(READ_ONLY_MODE); 146 147 Log(LOG_ADMIN, source, this) << "DEL " << na->nick; 148 source.Reply(_("Oper privileges removed from %s (%s)."), na->nick.c_str(), na->nc->display.c_str()); 149 } 150 } 151 else if (subcommand.equals_ci("LIST")) 152 { 153 source.Reply(_("Name Type")); 154 for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it) 155 { 156 const NickCore *nc = it->second; 157 158 if (!nc->o) 159 continue; 160 161 source.Reply(_("%-8s %s"), nc->o->name.c_str(), nc->o->ot->GetName().c_str()); 162 if (std::find(Config->Opers.begin(), Config->Opers.end(), nc->o) != Config->Opers.end()) 163 source.Reply(_(" This oper is configured in the configuration file.")); 164 for (std::list<User *>::const_iterator uit = nc->users.begin(); uit != nc->users.end(); ++uit) 165 { 166 User *u = *uit; 167 source.Reply(_(" %s is online using this oper block."), u->nick.c_str()); 168 } 169 } 170 } 171 else if (subcommand.equals_ci("INFO")) 172 { 173 if (params.size() < 2) 174 { 175 source.Reply(_("Available opertypes:")); 176 for (unsigned i = 0; i < Config->MyOperTypes.size(); ++i) 177 { 178 OperType *ot = Config->MyOperTypes[i]; 179 source.Reply("%s", ot->GetName().c_str()); 180 } 181 return; 182 } 183 184 Anope::string fulltype = params[1]; 185 if (params.size() > 2) 186 fulltype += " " + params[2]; 187 OperType *ot = OperType::Find(fulltype); 188 if (ot == NULL) 189 source.Reply(_("Oper type \002%s\002 has not been configured."), fulltype.c_str()); 190 else 191 { 192 if (ot->GetCommands().empty()) 193 source.Reply(_("Opertype \002%s\002 has no allowed commands."), ot->GetName().c_str()); 194 else 195 { 196 source.Reply(_("Available commands for \002%s\002:"), ot->GetName().c_str()); 197 Anope::string buf; 198 std::list<Anope::string> cmds = ot->GetCommands(); 199 for (std::list<Anope::string>::const_iterator it = cmds.begin(), it_end = cmds.end(); it != it_end; ++it) 200 { 201 buf += *it + " "; 202 if (buf.length() > 400) 203 { 204 source.Reply("%s", buf.c_str()); 205 buf.clear(); 206 } 207 } 208 if (!buf.empty()) 209 { 210 source.Reply("%s", buf.c_str()); 211 buf.clear(); 212 } 213 } 214 if (ot->GetPrivs().empty()) 215 source.Reply(_("Opertype \002%s\002 has no allowed privileges."), ot->GetName().c_str()); 216 else 217 { 218 source.Reply(_("Available privileges for \002%s\002:"), ot->GetName().c_str()); 219 Anope::string buf; 220 std::list<Anope::string> privs = ot->GetPrivs(); 221 for (std::list<Anope::string>::const_iterator it = privs.begin(), it_end = privs.end(); it != it_end; ++it) 222 { 223 buf += *it + " "; 224 if (buf.length() > 400) 225 { 226 source.Reply("%s", buf.c_str()); 227 buf.clear(); 228 } 229 } 230 if (!buf.empty()) 231 { 232 source.Reply("%s", buf.c_str()); 233 buf.clear(); 234 } 235 } 236 if (!ot->modes.empty()) 237 source.Reply(_("Opertype \002%s\002 receives modes \002%s\002 once identified."), ot->GetName().c_str(), ot->modes.c_str()); 238 } 239 } 240 else 241 this->OnSyntaxError(source, subcommand); 242 243 return; 244 } 245 246 bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override 247 { 248 this->SendSyntax(source); 249 source.Reply(" "); 250 source.Reply(_("Allows you to change and view Services Operators.\n" 251 "Note that operators removed by this command but are still set in\n" 252 "the configuration file are not permanently affected by this.")); 253 return true; 254 } 255 }; 256 257 class OSOper : public Module 258 { 259 Serialize::Type myoper_type; 260 CommandOSOper commandosoper; 261 262 public: 263 OSOper(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), 264 myoper_type("Oper", MyOper::Unserialize), commandosoper(this) 265 { 266 } 267 268 ~OSOper() 269 { 270 for (nickcore_map::const_iterator it = NickCoreList->begin(), it_end = NickCoreList->end(); it != it_end; ++it) 271 { 272 NickCore *nc = it->second; 273 274 if (nc->o && dynamic_cast<MyOper *>(nc->o)) 275 { 276 delete nc->o; 277 nc->o = NULL; 278 } 279 } 280 } 281 282 void OnDelCore(NickCore *nc) anope_override 283 { 284 if (nc->o && dynamic_cast<MyOper *>(nc->o)) 285 { 286 delete nc->o; 287 nc->o = NULL; 288 } 289 } 290 }; 291 292 MODULE_INIT(OSOper)