diff options
Diffstat (limited to 'modules/commands')
| -rw-r--r-- | modules/commands/cs_access.cpp | 72 | ||||
| -rw-r--r-- | modules/commands/cs_flags.cpp | 53 | ||||
| -rw-r--r-- | modules/commands/cs_xop.cpp | 58 |
3 files changed, 145 insertions, 38 deletions
diff --git a/modules/commands/cs_access.cpp b/modules/commands/cs_access.cpp index 8562efeb4..9a90b7d5f 100644 --- a/modules/commands/cs_access.cpp +++ b/modules/commands/cs_access.cpp @@ -128,16 +128,47 @@ class CommandCSAccess : public Command } } - if (mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (IRCD->IsChannelValid(mask)) { - User *targ = User::Find(mask, true); - if (targ != NULL) - mask = "*!*@" + targ->GetDisplayedHost(); - else + if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access")) { - source.Reply(NICK_X_NOT_REGISTERED, mask.c_str()); + source.Reply(_("Channels may not be on access lists.")); + return; + } + + ChannelInfo *targ_ci = ChannelInfo::Find(mask); + if (targ_ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str()); + return; + } + else if (ci == targ_ci) + { + source.Reply(_("You can't add a channel to its own access list.")); return; } + + mask = targ_ci->name; + } + else + { + const NickAlias *na = NickAlias::Find(mask); + if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access")) + { + source.Reply(_("Masks and unregistered users may not be on access lists.")); + return; + } + else if (mask.find_first_of("!*@") == Anope::string::npos && !na) + { + User *targ = User::Find(mask, true); + if (targ != NULL) + mask = "*!*@" + targ->GetDisplayedHost(); + else + { + source.Reply(NICK_X_NOT_REGISTERED, mask.c_str()); + return; + } + } } for (unsigned i = ci->GetAccessCount(); i > 0; --i) @@ -151,15 +182,15 @@ class CommandCSAccess : public Command source.Reply(ACCESS_DENIED); return; } - ci->EraseAccess(i - 1); + delete ci->EraseAccess(i - 1); break; } } unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); - if (access_max && ci->GetAccessCount() >= access_max) + if (access_max && ci->GetDeepAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max); + source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max); return; } @@ -187,7 +218,7 @@ class CommandCSAccess : public Command { Anope::string mask = params[2]; - if (!isdigit(mask[0]) && mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask)) { User *targ = User::Find(mask, true); if (targ != NULL) @@ -258,9 +289,10 @@ class CommandCSAccess : public Command else Nicks = access->mask; - FOREACH_MOD(OnAccessDel, (ci, source, access)); - ci->EraseAccess(Number - 1); + + FOREACH_MOD(OnAccessDel, (ci, source, access)); + delete access; } } delcallback(source, ci, this, mask); @@ -284,6 +316,7 @@ class CommandCSAccess : public Command bool override = !u_access.founder && !u_access.HasPriv("ACCESS_CHANGE") && !access->mask.equals_ci(source.nc->display); Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << access->mask; + ci->EraseAccess(i - 1); FOREACH_MOD(OnAccessDel, (ci, source, access)); delete access; } @@ -325,8 +358,11 @@ class CommandCSAccess : public Command Anope::string timebuf; if (ci->c) for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) - if (access->Matches(cit->second->user, cit->second->user->Account())) + { + ChanAccess::Path p; + if (access->Matches(cit->second->user, cit->second->user->Account(), p)) timebuf = "Now"; + } if (timebuf.empty()) { if (access->last_seen == 0) @@ -359,8 +395,11 @@ class CommandCSAccess : public Command Anope::string timebuf; if (ci->c) for (Channel::ChanUserList::const_iterator cit = ci->c->users.begin(), cit_end = ci->c->users.end(); cit != cit_end; ++cit) - if (access->Matches(cit->second->user, cit->second->user->Account())) + { + ChanAccess::Path p; + if (access->Matches(cit->second->user, cit->second->user->Account(), p)) timebuf = "Now"; + } if (timebuf.empty()) { if (access->last_seen == 0) @@ -527,10 +566,13 @@ class CommandCSAccess : public Command "the level specified in the command. The \037level\037 specified\n" "must be less than that of the user giving the command, and\n" "if the \037mask\037 is already on the access list, the current\n" - "access level of that nick must be less than the access level\n" + "access level of that mask must be less than the access level\n" "of the user giving the command. When a user joins the channel\n" "the access they receive is from the highest level entry in the\n" "access list.")); + if (!Config->GetModule("chanserv")->Get<bool>("disallow_channel_access")) + source.Reply(_("The given mask may also be a channel, which will use the\n" + "access list from the other channel up to the given \037level\037")); source.Reply(" "); source.Reply(_("The \002ACCESS DEL\002 command removes the given nick from the\n" "access list. If a list of entry numbers is given, those\n" diff --git a/modules/commands/cs_flags.cpp b/modules/commands/cs_flags.cpp index 23e6914d3..50c8e6b49 100644 --- a/modules/commands/cs_flags.cpp +++ b/modules/commands/cs_flags.cpp @@ -84,23 +84,55 @@ class CommandCSFlags : public Command AccessGroup u_access = source.AccessFor(ci); - if (mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (IRCD->IsChannelValid(mask)) { - User *targ = User::Find(mask, true); - if (targ != NULL) - mask = "*!*@" + targ->GetDisplayedHost(); - else + if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access")) + { + source.Reply(_("Channels may not be on access lists.")); + return; + } + + ChannelInfo *targ_ci = ChannelInfo::Find(mask); + if (targ_ci == NULL) { - source.Reply(NICK_X_NOT_REGISTERED, mask.c_str()); + source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str()); return; } + else if (ci == targ_ci) + { + source.Reply(_("You can't add a channel to its own access list.")); + return; + } + + mask = targ_ci->name; + } + else + { + const NickAlias *na = NickAlias::Find(mask); + if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access")) + { + source.Reply(_("Masks and unregistered users may not be on access lists.")); + return; + } + else if (mask.find_first_of("!*@") == Anope::string::npos && !na) + { + User *targ = User::Find(mask, true); + if (targ != NULL) + mask = "*!*@" + targ->GetDisplayedHost(); + else + { + source.Reply(NICK_X_NOT_REGISTERED, mask.c_str()); + return; + } + } } ChanAccess *current = NULL; + unsigned current_idx; std::set<char> current_flags; - for (unsigned i = ci->GetAccessCount(); i > 0; --i) + for (current_idx = ci->GetAccessCount(); current_idx > 0; --current_idx) { - ChanAccess *access = ci->GetAccess(i - 1); + ChanAccess *access = ci->GetAccess(current_idx - 1); if (mask.equals_ci(access->mask)) { current = access; @@ -112,9 +144,9 @@ class CommandCSFlags : public Command } unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); - if (access_max && ci->GetAccessCount() >= access_max) + if (access_max && ci->GetDeepAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d access entries on a channel."), access_max); + source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max); return; } @@ -178,6 +210,7 @@ class CommandCSFlags : public Command { if (current != NULL) { + ci->EraseAccess(current_idx - 1); FOREACH_MOD(OnAccessDel, (ci, source, current)); delete current; Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask; diff --git a/modules/commands/cs_xop.cpp b/modules/commands/cs_xop.cpp index 253dde884..db4faa657 100644 --- a/modules/commands/cs_xop.cpp +++ b/modules/commands/cs_xop.cpp @@ -132,16 +132,47 @@ class CommandCSXOP : public Command } } - if (mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (IRCD->IsChannelValid(mask)) { - User *targ = User::Find(mask, true); - if (targ != NULL) - mask = "*!*@" + targ->GetDisplayedHost(); - else + if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access")) { - source.Reply(NICK_X_NOT_REGISTERED, mask.c_str()); + source.Reply(_("Channels may not be on access lists.")); + return; + } + + ChannelInfo *targ_ci = ChannelInfo::Find(mask); + if (targ_ci == NULL) + { + source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str()); return; } + else if (ci == targ_ci) + { + source.Reply(_("You can't add a channel to its own access list.")); + return; + } + + mask = targ_ci->name; + } + else + { + const NickAlias *na = NickAlias::Find(mask); + if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access")) + { + source.Reply(_("Masks and unregistered users may not be on access lists.")); + return; + } + else if (mask.find_first_of("!*@") == Anope::string::npos && !na) + { + User *targ = User::Find(mask, true); + if (targ != NULL) + mask = "*!*@" + targ->GetDisplayedHost(); + else + { + source.Reply(NICK_X_NOT_REGISTERED, mask.c_str()); + return; + } + } } for (unsigned i = 0; i < ci->GetAccessCount(); ++i) @@ -156,15 +187,15 @@ class CommandCSXOP : public Command return; } - ci->EraseAccess(i); + delete ci->EraseAccess(i); break; } } unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024"); - if (access_max && ci->GetAccessCount() >= access_max) + if (access_max && ci->GetDeepAccessCount() >= access_max) { - source.Reply(_("Sorry, you can only have %d %s entries on a channel."), access_max, source.command.c_str()); + source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max); return; } @@ -217,7 +248,7 @@ class CommandCSXOP : public Command const ChanAccess *highest = access.Highest(); bool override = false; - if (!isdigit(mask[0]) && mask.find_first_of("!*@") == Anope::string::npos && !NickAlias::Find(mask)) + if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask)) { User *targ = User::Find(mask, true); if (targ != NULL) @@ -287,9 +318,9 @@ class CommandCSXOP : public Command else nicks = caccess->mask; - FOREACH_MOD(OnAccessDel, (ci, source, caccess)); - ci->EraseAccess(number - 1); + FOREACH_MOD(OnAccessDel, (ci, source, caccess)); + delete caccess; } } delcallback(source, ci, this, override, mask); @@ -307,6 +338,7 @@ class CommandCSXOP : public Command source.Reply(_("\002%s\002 deleted from %s %s list."), a->mask.c_str(), ci->name.c_str(), source.command.c_str()); + ci->EraseAccess(i); FOREACH_MOD(OnAccessDel, (ci, source, a)); delete a; @@ -428,7 +460,7 @@ class CommandCSXOP : public Command { const ChanAccess *access = ci->GetAccess(i - 1); if (XOPChanAccess::DetermineLevel(access) == source.command.upper()) - ci->EraseAccess(i - 1); + delete ci->EraseAccess(i - 1); } FOREACH_MOD(OnAccessClear, (ci, source)); |
