anope- supernets anope source code & configuration |
git clone git://git.acid.vegas/anope.git |
Log | Files | Refs | Archive | README |
access.cpp (11415B)
1 /* 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 "service.h" 13 #include "access.h" 14 #include "regchannel.h" 15 #include "users.h" 16 #include "account.h" 17 #include "protocol.h" 18 19 static struct 20 { 21 Anope::string name; 22 Anope::string desc; 23 } descriptions[] = { 24 {"ACCESS_CHANGE", _("Allowed to modify the access list")}, 25 {"ACCESS_LIST", _("Allowed to view the access list")}, 26 {"AKICK", _("Allowed to use the AKICK command")}, 27 {"ASSIGN", _("Allowed to assign/unassign a bot")}, 28 {"AUTOHALFOP", _("Automatic halfop upon join")}, 29 {"AUTOOP", _("Automatic channel operator status upon join")}, 30 {"AUTOOWNER", _("Automatic owner upon join")}, 31 {"AUTOPROTECT", _("Automatic protect upon join")}, 32 {"AUTOVOICE", _("Automatic voice on join")}, 33 {"BADWORDS", _("Allowed to modify channel badwords list")}, 34 {"BAN", _("Allowed to ban users")}, 35 {"FANTASIA", _("Allowed to use fantasy commands")}, 36 {"FOUNDER", _("Allowed to issue commands restricted to channel founders")}, 37 {"GETKEY", _("Allowed to use GETKEY command")}, 38 {"GREET", _("Greet message displayed on join")}, 39 {"HALFOP", _("Allowed to (de)halfop users")}, 40 {"HALFOPME", _("Allowed to (de)halfop him/herself")}, 41 {"INFO", _("Allowed to get full INFO output")}, 42 {"INVITE", _("Allowed to use the INVITE command")}, 43 {"KICK", _("Allowed to use the KICK command")}, 44 {"MEMO", _("Allowed to read channel memos")}, 45 {"MODE", _("Allowed to use the MODE command")}, 46 {"NOKICK", _("Prevents users being kicked by Services")}, 47 {"OP", _("Allowed to (de)op users")}, 48 {"OPME", _("Allowed to (de)op him/herself")}, 49 {"OWNER", _("Allowed to (de)owner users")}, 50 {"OWNERME", _("Allowed to (de)owner him/herself")}, 51 {"PROTECT", _("Allowed to (de)protect users")}, 52 {"PROTECTME", _("Allowed to (de)protect him/herself")}, 53 {"SAY", _("Allowed to use SAY and ACT commands")}, 54 {"SET", _("Allowed to set channel settings")}, 55 {"SIGNKICK", _("No signed kick when SIGNKICK LEVEL is used")}, 56 {"TOPIC", _("Allowed to change channel topics")}, 57 {"UNBAN", _("Allowed to unban users")}, 58 {"VOICE", _("Allowed to (de)voice users")}, 59 {"VOICEME", _("Allowed to (de)voice him/herself")} 60 }; 61 62 Privilege::Privilege(const Anope::string &n, const Anope::string &d, int r) : name(n), desc(d), rank(r) 63 { 64 if (this->desc.empty()) 65 for (unsigned j = 0; j < sizeof(descriptions) / sizeof(*descriptions); ++j) 66 if (descriptions[j].name.equals_ci(name)) 67 this->desc = descriptions[j].desc; 68 } 69 70 bool Privilege::operator==(const Privilege &other) const 71 { 72 return this->name.equals_ci(other.name); 73 } 74 75 std::vector<Privilege> PrivilegeManager::Privileges; 76 77 void PrivilegeManager::AddPrivilege(Privilege p) 78 { 79 unsigned i; 80 for (i = 0; i < Privileges.size(); ++i) 81 { 82 Privilege &priv = Privileges[i]; 83 84 if (priv.rank > p.rank) 85 break; 86 } 87 88 Privileges.insert(Privileges.begin() + i, p); 89 } 90 91 void PrivilegeManager::RemovePrivilege(Privilege &p) 92 { 93 std::vector<Privilege>::iterator it = std::find(Privileges.begin(), Privileges.end(), p); 94 if (it != Privileges.end()) 95 Privileges.erase(it); 96 97 for (registered_channel_map::const_iterator cit = RegisteredChannelList->begin(), cit_end = RegisteredChannelList->end(); cit != cit_end; ++cit) 98 { 99 cit->second->QueueUpdate(); 100 cit->second->RemoveLevel(p.name); 101 } 102 } 103 104 Privilege *PrivilegeManager::FindPrivilege(const Anope::string &name) 105 { 106 for (unsigned i = Privileges.size(); i > 0; --i) 107 if (Privileges[i - 1].name.equals_ci(name)) 108 return &Privileges[i - 1]; 109 return NULL; 110 } 111 112 std::vector<Privilege> &PrivilegeManager::GetPrivileges() 113 { 114 return Privileges; 115 } 116 117 void PrivilegeManager::ClearPrivileges() 118 { 119 Privileges.clear(); 120 } 121 122 AccessProvider::AccessProvider(Module *o, const Anope::string &n) : Service(o, "AccessProvider", n) 123 { 124 Providers.push_back(this); 125 } 126 127 AccessProvider::~AccessProvider() 128 { 129 std::list<AccessProvider *>::iterator it = std::find(Providers.begin(), Providers.end(), this); 130 if (it != Providers.end()) 131 Providers.erase(it); 132 } 133 134 std::list<AccessProvider *> AccessProvider::Providers; 135 136 const std::list<AccessProvider *>& AccessProvider::GetProviders() 137 { 138 return Providers; 139 } 140 141 ChanAccess::ChanAccess(AccessProvider *p) : Serializable("ChanAccess"), provider(p) 142 { 143 } 144 145 ChanAccess::~ChanAccess() 146 { 147 if (this->ci) 148 { 149 std::vector<ChanAccess *>::iterator it = std::find(this->ci->access->begin(), this->ci->access->end(), this); 150 if (it != this->ci->access->end()) 151 this->ci->access->erase(it); 152 153 if (*nc != NULL) 154 nc->RemoveChannelReference(this->ci); 155 else 156 { 157 ChannelInfo *c = ChannelInfo::Find(this->mask); 158 if (c) 159 c->RemoveChannelReference(this->ci->name); 160 } 161 } 162 } 163 164 void ChanAccess::SetMask(const Anope::string &m, ChannelInfo *c) 165 { 166 if (*nc != NULL) 167 nc->RemoveChannelReference(this->ci); 168 else if (!this->mask.empty()) 169 { 170 ChannelInfo *targc = ChannelInfo::Find(this->mask); 171 if (targc) 172 targc->RemoveChannelReference(this->ci->name); 173 } 174 175 ci = c; 176 mask.clear(); 177 nc = NULL; 178 179 const NickAlias *na = NickAlias::Find(m); 180 if (na != NULL) 181 { 182 nc = na->nc; 183 nc->AddChannelReference(ci); 184 } 185 else 186 { 187 mask = m; 188 189 ChannelInfo *targci = ChannelInfo::Find(mask); 190 if (targci != NULL) 191 targci->AddChannelReference(ci->name); 192 } 193 } 194 195 const Anope::string &ChanAccess::Mask() const 196 { 197 if (nc) 198 return nc->display; 199 else 200 return mask; 201 } 202 203 NickCore *ChanAccess::GetAccount() const 204 { 205 return nc; 206 } 207 208 void ChanAccess::Serialize(Serialize::Data &data) const 209 { 210 data["provider"] << this->provider->name; 211 data["ci"] << this->ci->name; 212 data["mask"] << this->Mask(); 213 data["creator"] << this->creator; 214 data.SetType("last_seen", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen; 215 data.SetType("created", Serialize::Data::DT_INT); data["created"] << this->created; 216 data["data"] << this->AccessSerialize(); 217 } 218 219 Serializable* ChanAccess::Unserialize(Serializable *obj, Serialize::Data &data) 220 { 221 Anope::string provider, chan; 222 223 data["provider"] >> provider; 224 data["ci"] >> chan; 225 226 ServiceReference<AccessProvider> aprovider("AccessProvider", provider); 227 ChannelInfo *ci = ChannelInfo::Find(chan); 228 if (!aprovider || !ci) 229 return NULL; 230 231 ChanAccess *access; 232 if (obj) 233 access = anope_dynamic_static_cast<ChanAccess *>(obj); 234 else 235 access = aprovider->Create(); 236 access->ci = ci; 237 Anope::string m; 238 data["mask"] >> m; 239 access->SetMask(m, ci); 240 data["creator"] >> access->creator; 241 data["last_seen"] >> access->last_seen; 242 data["created"] >> access->created; 243 244 Anope::string adata; 245 data["data"] >> adata; 246 access->AccessUnserialize(adata); 247 248 if (!obj) 249 ci->AddAccess(access); 250 return access; 251 } 252 253 bool ChanAccess::Matches(const User *u, const NickCore *acc, ChannelInfo* &next) const 254 { 255 next = NULL; 256 257 if (this->nc) 258 return this->nc == acc; 259 260 if (u) 261 { 262 bool is_mask = this->mask.find_first_of("!@?*") != Anope::string::npos; 263 if (is_mask && Anope::Match(u->nick, this->mask)) 264 return true; 265 else if (Anope::Match(u->GetDisplayedMask(), this->mask)) 266 return true; 267 } 268 269 if (acc) 270 { 271 for (unsigned i = 0; i < acc->aliases->size(); ++i) 272 { 273 const NickAlias *na = acc->aliases->at(i); 274 if (Anope::Match(na->nick, this->mask)) 275 return true; 276 } 277 } 278 279 if (IRCD->IsChannelValid(this->mask)) 280 { 281 next = ChannelInfo::Find(this->mask); 282 } 283 284 return false; 285 } 286 287 bool ChanAccess::operator>(const ChanAccess &other) const 288 { 289 const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); 290 for (unsigned i = privs.size(); i > 0; --i) 291 { 292 bool this_p = this->HasPriv(privs[i - 1].name), 293 other_p = other.HasPriv(privs[i - 1].name); 294 295 if (!this_p && !other_p) 296 continue; 297 298 return this_p && !other_p; 299 } 300 301 return false; 302 } 303 304 bool ChanAccess::operator<(const ChanAccess &other) const 305 { 306 const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); 307 for (unsigned i = privs.size(); i > 0; --i) 308 { 309 bool this_p = this->HasPriv(privs[i - 1].name), 310 other_p = other.HasPriv(privs[i - 1].name); 311 312 if (!this_p && !other_p) 313 continue; 314 315 return !this_p && other_p; 316 } 317 318 return false; 319 } 320 321 bool ChanAccess::operator>=(const ChanAccess &other) const 322 { 323 return !(*this < other); 324 } 325 326 bool ChanAccess::operator<=(const ChanAccess &other) const 327 { 328 return !(*this > other); 329 } 330 331 AccessGroup::AccessGroup() 332 { 333 this->ci = NULL; 334 this->nc = NULL; 335 this->super_admin = this->founder = false; 336 } 337 338 static bool HasPriv(const ChanAccess::Path &path, const Anope::string &name) 339 { 340 if (path.empty()) 341 return false; 342 343 for (unsigned int i = 0; i < path.size(); ++i) 344 { 345 ChanAccess *access = path[i]; 346 347 EventReturn MOD_RESULT; 348 FOREACH_RESULT(OnCheckPriv, MOD_RESULT, (access, name)); 349 350 if (MOD_RESULT != EVENT_ALLOW && !access->HasPriv(name)) 351 return false; 352 } 353 354 return true; 355 } 356 357 bool AccessGroup::HasPriv(const Anope::string &name) const 358 { 359 if (this->super_admin) 360 return true; 361 else if (!ci || ci->GetLevel(name) == ACCESS_INVALID) 362 return false; 363 364 /* Privileges prefixed with auto are understood to be given 365 * automatically. Sometimes founders want to not automatically 366 * obtain privileges, so we will let them */ 367 bool auto_mode = !name.find("AUTO"); 368 369 /* Only grant founder privilege if this isn't an auto mode or if they don't match any entries in this group */ 370 if ((!auto_mode || paths.empty()) && this->founder) 371 return true; 372 373 EventReturn MOD_RESULT; 374 FOREACH_RESULT(OnGroupCheckPriv, MOD_RESULT, (this, name)); 375 if (MOD_RESULT != EVENT_CONTINUE) 376 return MOD_RESULT == EVENT_ALLOW; 377 378 for (unsigned int i = paths.size(); i > 0; --i) 379 { 380 const ChanAccess::Path &path = paths[i - 1]; 381 382 if (::HasPriv(path, name)) 383 return true; 384 } 385 386 return false; 387 } 388 389 static ChanAccess *HighestInPath(const ChanAccess::Path &path) 390 { 391 ChanAccess *highest = NULL; 392 393 for (unsigned int i = 0; i < path.size(); ++i) 394 if (highest == NULL || *path[i] > *highest) 395 highest = path[i]; 396 397 return highest; 398 } 399 400 const ChanAccess *AccessGroup::Highest() const 401 { 402 ChanAccess *highest = NULL; 403 404 for (unsigned int i = 0; i < paths.size(); ++i) 405 { 406 ChanAccess *hip = HighestInPath(paths[i]); 407 408 if (highest == NULL || *hip > *highest) 409 highest = hip; 410 } 411 412 return highest; 413 } 414 415 bool AccessGroup::operator>(const AccessGroup &other) const 416 { 417 if (other.super_admin) 418 return false; 419 else if (this->super_admin) 420 return true; 421 else if (other.founder) 422 return false; 423 else if (this->founder) 424 return true; 425 426 const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); 427 for (unsigned i = privs.size(); i > 0; --i) 428 { 429 bool this_p = this->HasPriv(privs[i - 1].name), 430 other_p = other.HasPriv(privs[i - 1].name); 431 432 if (!this_p && !other_p) 433 continue; 434 435 return this_p && !other_p; 436 } 437 438 return false; 439 } 440 441 bool AccessGroup::operator<(const AccessGroup &other) const 442 { 443 if (this->super_admin) 444 return false; 445 else if (other.super_admin) 446 return true; 447 else if (this->founder) 448 return false; 449 else if (other.founder) 450 return true; 451 452 const std::vector<Privilege> &privs = PrivilegeManager::GetPrivileges(); 453 for (unsigned i = privs.size(); i > 0; --i) 454 { 455 bool this_p = this->HasPriv(privs[i - 1].name), 456 other_p = other.HasPriv(privs[i - 1].name); 457 458 if (!this_p && !other_p) 459 continue; 460 461 return !this_p && other_p; 462 } 463 464 return false; 465 } 466 467 bool AccessGroup::operator>=(const AccessGroup &other) const 468 { 469 return !(*this < other); 470 } 471 472 bool AccessGroup::operator<=(const AccessGroup &other) const 473 { 474 return !(*this > other); 475 }