diff options
| author | Adam <Adam@anope.org> | 2010-11-30 03:02:33 -0500 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2010-12-12 19:37:02 -0500 |
| commit | 0ba566491ea246fcc895862d0ef80bdf4ee43b4b (patch) | |
| tree | 9852671d32476ddad58e264a8e074c41fef9f69f | |
| parent | 2a4d57a1cacd22084abea5dd21c87dc733a7b5bf (diff) | |
Allowing adding hostmasks to channel access lists
| -rw-r--r-- | include/extern.h | 5 | ||||
| -rw-r--r-- | include/language.h | 6 | ||||
| -rw-r--r-- | include/modules.h | 14 | ||||
| -rw-r--r-- | include/regchannel.h | 37 | ||||
| -rw-r--r-- | include/services.h | 3 | ||||
| -rw-r--r-- | modules/core/cs_access.cpp | 111 | ||||
| -rw-r--r-- | modules/core/cs_akick.cpp | 12 | ||||
| -rw-r--r-- | modules/core/cs_ban.cpp | 10 | ||||
| -rw-r--r-- | modules/core/cs_clone.cpp | 2 | ||||
| -rw-r--r-- | modules/core/cs_kick.cpp | 10 | ||||
| -rw-r--r-- | modules/core/cs_modes.cpp | 10 | ||||
| -rw-r--r-- | modules/core/cs_register.cpp | 4 | ||||
| -rw-r--r-- | modules/core/cs_status.cpp | 3 | ||||
| -rw-r--r-- | modules/core/cs_xop.cpp | 119 | ||||
| -rw-r--r-- | modules/core/db_plain.cpp | 12 | ||||
| -rw-r--r-- | modules/core/ms_staff.cpp | 1 | ||||
| -rw-r--r-- | modules/core/ns_access.cpp | 3 | ||||
| -rw-r--r-- | modules/core/ns_alist.cpp | 12 | ||||
| -rw-r--r-- | modules/extra/db_mysql.cpp | 23 | ||||
| -rw-r--r-- | src/botserv.cpp | 18 | ||||
| -rw-r--r-- | src/channels.cpp | 6 | ||||
| -rw-r--r-- | src/chanserv.cpp | 80 | ||||
| -rw-r--r-- | src/language.cpp | 50 | ||||
| -rw-r--r-- | src/regchannel.cpp | 124 |
24 files changed, 340 insertions, 335 deletions
diff --git a/include/extern.h b/include/extern.h index de51742ab..24f12a84f 100644 --- a/include/extern.h +++ b/include/extern.h @@ -63,8 +63,6 @@ E Channel *findchan(const Anope::string &chan); E User *nc_on_chan(Channel *c, const NickCore *nc); -E int get_access_level(ChannelInfo *ci, NickAlias *na); -E int get_access_level(ChannelInfo *ci, NickCore *nc); E Anope::string get_xop_level(int level); E void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts); @@ -91,7 +89,7 @@ E void get_chanserv_stats(long *nrec, long *memuse); E void reset_levels(ChannelInfo *ci); E void cs_init(); E void expire_chans(); -E void cs_remove_nick(const NickCore *nc); +E void cs_remove_nick(NickCore *nc); E void check_modes(Channel *c); E int check_valid_admin(User *user, Channel *chan, int servermode); @@ -100,7 +98,6 @@ E int check_valid_op(User *user, Channel *chan, int servermode); E ChannelInfo *cs_findchan(const Anope::string &chan); E int check_access(User *user, ChannelInfo *ci, int what); E bool IsFounder(User *user, ChannelInfo *ci); -E int get_access(User *user, ChannelInfo *ci); E void update_cs_lastseen(User *user, ChannelInfo *ci); E int get_idealban(ChannelInfo *ci, User *u, Anope::string &ret); diff --git a/include/language.h b/include/language.h index 0b880a2f5..4b04028f9 100644 --- a/include/language.h +++ b/include/language.h @@ -392,7 +392,6 @@ enum LanguageString CHAN_XOP_NOT_AVAILABLE, CHAN_QOP_SYNTAX, CHAN_QOP_DISABLED, - CHAN_QOP_NICKS_ONLY, CHAN_QOP_ADDED, CHAN_QOP_MOVED, CHAN_QOP_NO_SUCH_ENTRY, @@ -406,7 +405,6 @@ enum LanguageString CHAN_QOP_CLEAR, CHAN_AOP_SYNTAX, CHAN_AOP_DISABLED, - CHAN_AOP_NICKS_ONLY, CHAN_AOP_ADDED, CHAN_AOP_MOVED, CHAN_AOP_NO_SUCH_ENTRY, @@ -420,7 +418,6 @@ enum LanguageString CHAN_AOP_CLEAR, CHAN_HOP_SYNTAX, CHAN_HOP_DISABLED, - CHAN_HOP_NICKS_ONLY, CHAN_HOP_ADDED, CHAN_HOP_MOVED, CHAN_HOP_NO_SUCH_ENTRY, @@ -434,7 +431,6 @@ enum LanguageString CHAN_HOP_CLEAR, CHAN_SOP_SYNTAX, CHAN_SOP_DISABLED, - CHAN_SOP_NICKS_ONLY, CHAN_SOP_ADDED, CHAN_SOP_MOVED, CHAN_SOP_NO_SUCH_ENTRY, @@ -448,7 +444,6 @@ enum LanguageString CHAN_SOP_CLEAR, CHAN_VOP_SYNTAX, CHAN_VOP_DISABLED, - CHAN_VOP_NICKS_ONLY, CHAN_VOP_ADDED, CHAN_VOP_MOVED, CHAN_VOP_NO_SUCH_ENTRY, @@ -466,7 +461,6 @@ enum LanguageString CHAN_ACCESS_DISABLED, CHAN_ACCESS_LEVEL_NONZERO, CHAN_ACCESS_LEVEL_RANGE, - CHAN_ACCESS_NICKS_ONLY, CHAN_ACCESS_REACHED_LIMIT, CHAN_ACCESS_LEVEL_UNCHANGED, CHAN_ACCESS_LEVEL_CHANGED, diff --git a/include/modules.h b/include/modules.h index 12e7884f8..c96c1ae27 100644 --- a/include/modules.h +++ b/include/modules.h @@ -723,25 +723,23 @@ class CoreExport Module : public Extensible /** Called when access is deleted from a channel * @param ci The channel * @param u The user who removed the access - * @param nc The user who was deleted + * @param access The access entry being removed */ - virtual void OnAccessDel(ChannelInfo *ci, User *u, NickCore *nc) { } + virtual void OnAccessDel(ChannelInfo *ci, User *u, ChanAccess *access) { } /** Called when access is changed * @param ci The channel * @param u The user who changed the access - * @param nc The nick whos access was changed - * @param level The level of the new access + * @param u access The access changed */ - virtual void OnAccessChange(ChannelInfo *ci, User *u, NickCore *nc, int level) { } + virtual void OnAccessChange(ChannelInfo *ci, User *u, ChanAccess *access) { } /** Called when access is added * @param ci The channel * @param u The user who added the access - * @para nc The nick who was added to access - * @param level The level they were added at + * @param access The access changed */ - virtual void OnAccessAdd(ChannelInfo *ci, User *u, NickCore *nc, int level) { } + virtual void OnAccessAdd(ChannelInfo *ci, User *u, ChanAccess *access) { } /** Called when the access list is cleared * @param ci The channel diff --git a/include/regchannel.h b/include/regchannel.h index 760a91f5f..71deb1ce7 100644 --- a/include/regchannel.h +++ b/include/regchannel.h @@ -132,14 +132,15 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, /** Add an entry to the channel access list * - * @param nc The NickCore of the user that the access entry should be tied to + * @param mask The mask of the access entry * @param level The channel access level the user has on the channel * @param creator The user who added the access * @param last_seen When the user was last seen within the channel + * @return The new access class * * Creates a new access list entry and inserts it into the access list. */ - void AddAccess(NickCore *nc, int16 level, const Anope::string &creator, int32 last_seen = 0); + ChanAccess *AddAccess(const Anope::string &mask, int16 level, const Anope::string &creator, int32 last_seen = 0); /** Get an entry from the channel access list by index * @@ -150,15 +151,35 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, */ ChanAccess *GetAccess(unsigned index); + /** Get an entry from the channel access list by User + * + * @param u The User to find within the access list vector + * @param level Optional channel access level to compare the access entries to + * @return A ChanAccess struct corresponding to the User, or NULL if not found + * + * Retrieves an entry from the access list that matches the given User, optionally also matching a certain level. + */ + ChanAccess *GetAccess(User *u, int16 level = 0); + /** Get an entry from the channel access list by NickCore * - * @param nc The NickCore to find within the access list vector + * @param u The NickCore to find within the access list vector * @param level Optional channel access level to compare the access entries to * @return A ChanAccess struct corresponding to the NickCore, or NULL if not found * * Retrieves an entry from the access list that matches the given NickCore, optionally also matching a certain level. */ - ChanAccess *GetAccess(const NickCore *nc, int16 level = 0); + ChanAccess *GetAccess(NickCore *nc, int16 level = 0); + + /** Get an entry from the channel access list by mask + * + * @param u The mask to find within the access list vector + * @param level Optional channel access level to compare the access entries to + * @return A ChanAccess struct corresponding to the mask, or NULL if not found + * + * Retrieves an entry from the access list that matches the given mask, optionally also matching a certain level. + */ + ChanAccess *GetAccess(const Anope::string &mask, int16 level = 0); /** Get the size of the accss vector for this channel * @return The access vector size @@ -173,6 +194,14 @@ class CoreExport ChannelInfo : public Extensible, public Flags<ChannelInfoFlag, */ void EraseAccess(unsigned index); + /** Erase an entry from the channel access list + * + * @param access The access to remove + * + * Clears the memory used by the given access entry and removes it from the vector. + */ + void EraseAccess(ChanAccess *access); + /** Clear the entire channel access list * * Clears the entire access list by deleting every item and then clearing the vector. diff --git a/include/services.h b/include/services.h index 16be4ebc7..2b4c13f7c 100644 --- a/include/services.h +++ b/include/services.h @@ -571,7 +571,8 @@ enum AccessLevel struct ChanAccess { int16 level; - NickCore *nc; /* Guaranteed to be non-NULL if in use, NULL if not */ + Anope::string mask; /* Mask of the access entry */ + NickCore *nc; /* NC of the entry, if the entry is a valid nickcore */ time_t last_seen; Anope::string creator; }; diff --git a/modules/core/cs_access.cpp b/modules/core/cs_access.cpp index 96856da60..43cb58cf1 100644 --- a/modules/core/cs_access.cpp +++ b/modules/core/cs_access.cpp @@ -50,10 +50,10 @@ class AccessListCallback : public NumberList if (source.ci->HasFlag(CI_XOP)) { Anope::string xop = get_xop_level(access->level); - source.Reply(CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str()); + source.Reply(CHAN_ACCESS_LIST_XOP_FORMAT, Number + 1, xop.c_str(), access->mask.c_str()); } else - source.Reply(CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str()); + source.Reply(CHAN_ACCESS_LIST_AXS_FORMAT, Number + 1, access->level, access->mask.c_str()); } }; @@ -93,10 +93,10 @@ class AccessViewCallback : public AccessListCallback if (ci->HasFlag(CI_XOP)) { Anope::string xop = get_xop_level(access->level); - source.Reply(CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop.c_str(), access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str()); + source.Reply(CHAN_ACCESS_VIEW_XOP_FORMAT, Number + 1, xop.c_str(), access->mask.c_str(), access->creator.c_str(), timebuf.c_str()); } else - source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->nc->display.c_str(), access->creator.c_str(), timebuf.c_str()); + source.Reply(CHAN_ACCESS_VIEW_AXS_FORMAT, Number + 1, access->level, access->mask.c_str(), access->creator.c_str(), timebuf.c_str()); } }; @@ -142,7 +142,9 @@ class AccessDelCallback : public NumberList ChanAccess *access = ci->GetAccess(Number - 1); - if (get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + ChanAccess *u_access = ci->GetAccess(u); + int16 u_level = u_access ? u_access->level : 0; + if (u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) { Denied = true; return; @@ -150,11 +152,11 @@ class AccessDelCallback : public NumberList ++Deleted; if (!Nicks.empty()) - Nicks += ", " + access->nc->display; + Nicks += ", " + access->mask; else - Nicks = access->nc->display; + Nicks = access->mask; - FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access->nc)); + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access)); ci->EraseAccess(Number - 1); } @@ -167,11 +169,12 @@ class CommandCSAccess : public Command User *u = source.u; ChannelInfo *ci = source.ci; - const Anope::string &nick = params[2]; + Anope::string mask = params[2]; int level = params[3].is_number_only() ? convertTo<int>(params[3]) : ACCESS_INVALID; - int ulev = get_access(u, ci); - if (level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) + ChanAccess *u_access = ci->GetAccess(u); + int16 u_level = u_access ? u_access->level : 0; + if (level >= u_level && !u->Account()->HasPriv("chanserv/access/modify")) { source.Reply(ACCESS_DENIED); return MOD_CONT; @@ -188,41 +191,37 @@ class CommandCSAccess : public Command return MOD_CONT; } - bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= ulev; + bool override = !check_access(u, ci, CA_ACCESS_CHANGE) || level >= u_level; - NickAlias *na = findnick(nick); - if (!na) + NickAlias *na = findnick(mask); + if (!na && mask.find_first_of("!@*") == Anope::string::npos) + mask += "!*@*"; + else if (na && na->HasFlag(NS_FORBIDDEN)) { - source.Reply(CHAN_ACCESS_NICKS_ONLY); - return MOD_CONT; - } - else if (na->HasFlag(NS_FORBIDDEN)) - { - source.Reply(NICK_X_FORBIDDEN, nick.c_str()); + source.Reply(NICK_X_FORBIDDEN, mask.c_str()); return MOD_CONT; } - NickCore *nc = na->nc; - ChanAccess *access = ci->GetAccess(nc); + ChanAccess *access = ci->GetAccess(mask); if (access) { - /* Don't allow lowering from a level >= ulev */ - if (access->level >= ulev && !u->Account()->HasPriv("chanserv/access/modify")) + /* Don't allow lowering from a level >= u_level */ + if (access->level >= u_level && !u->Account()->HasPriv("chanserv/access/modify")) { source.Reply(ACCESS_DENIED); return MOD_CONT; } if (access->level == level) { - source.Reply(CHAN_ACCESS_LEVEL_UNCHANGED, access->nc->display.c_str(), ci->name.c_str(), level); + source.Reply(CHAN_ACCESS_LEVEL_UNCHANGED, access->mask.c_str(), ci->name.c_str(), level); return MOD_CONT; } access->level = level; - FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, level)); + FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, access)); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev; - source.Reply(CHAN_ACCESS_LEVEL_CHANGED, nc->display.c_str(), ci->name.c_str(), level); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (level: " << level << ") as level " << u_level; + source.Reply(CHAN_ACCESS_LEVEL_CHANGED, access->mask.c_str(), ci->name.c_str(), level); return MOD_CONT; } @@ -232,12 +231,12 @@ class CommandCSAccess : public Command return MOD_CONT; } - ci->AddAccess(nc, level, u->nick); + access = ci->AddAccess(mask, level, u->nick); - FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level)); + FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access)); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") (level: " << level << ") as level " << ulev; - source.Reply(CHAN_ACCESS_ADDED, nc->display.c_str(), ci->name.c_str(), level); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " (level: " << level << ") as level " << u_level; + source.Reply(CHAN_ACCESS_ADDED, access->mask.c_str(), ci->name.c_str(), level); return MOD_CONT; } @@ -247,49 +246,33 @@ class CommandCSAccess : public Command User *u = source.u; ChannelInfo *ci = source.ci; - const Anope::string &nick = params[2]; + const Anope::string &mask = params[2]; if (!ci->GetAccessCount()) source.Reply(CHAN_ACCESS_LIST_EMPTY, ci->name.c_str()); - else if (isdigit(nick[0]) && nick.find_first_not_of("1234567890,-") == Anope::string::npos) + else if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos) { - AccessDelCallback list(source, this, nick); + AccessDelCallback list(source, this, mask); list.Process(); } else { - NickAlias *na = findnick(nick); - if (!na) - { - source.Reply(NICK_X_NOT_REGISTERED, nick.c_str()); - return MOD_CONT; - } - - NickCore *nc = na->nc; - - unsigned i, end; - ChanAccess *access = NULL; - for (i = 0, end = ci->GetAccessCount(); i < end; ++i) - { - access = ci->GetAccess(i); - - if (access->nc == nc) - break; - } - - if (i == end) - source.Reply(CHAN_ACCESS_NOT_FOUND, nick.c_str(), ci->name.c_str()); - else if (nc != u->Account() && check_access(u, ci, CA_NOJOIN) && get_access(u, ci) <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) + ChanAccess *access = ci->GetAccess(mask); + ChanAccess *u_access = ci->GetAccess(u); + int16 u_level = u_access ? u_access->level : 0; + if (!access) + source.Reply(CHAN_ACCESS_NOT_FOUND, mask.c_str(), ci->name.c_str()); + else if (access->nc != u->Account() && check_access(u, ci, CA_NOJOIN) && u_level <= access->level && !u->Account()->HasPriv("chanserv/access/modify")) source.Reply(ACCESS_DENIED); else { - source.Reply(CHAN_ACCESS_DELETED, access->nc->display.c_str(), ci->name.c_str()); - bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && nc != u->Account(); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << na->nick << " (group: " << access->nc->display << ") from level " << access->level; + source.Reply(CHAN_ACCESS_DELETED, access->mask.c_str(), ci->name.c_str()); + bool override = !check_access(u, ci, CA_ACCESS_CHANGE) && access->nc != u->Account(); + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "DEL " << access->mask << " from level " << access->level; - FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, na->nc)); + FOREACH_MOD(I_OnAccessDel, OnAccessDel(ci, u, access)); - ci->EraseAccess(i); + ci->EraseAccess(access); } } @@ -317,7 +300,7 @@ class CommandCSAccess : public Command { ChanAccess *access = ci->GetAccess(i); - if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick)) + if (!nick.empty() && !Anope::Match(access->mask, nick)) continue; if (!SentHeader) @@ -359,7 +342,7 @@ class CommandCSAccess : public Command { ChanAccess *access = ci->GetAccess(i); - if (!nick.empty() && access->nc && !Anope::Match(access->nc->display, nick)) + if (!nick.empty() && !Anope::Match(access->mask, nick)) continue; if (!SentHeader) diff --git a/modules/core/cs_akick.cpp b/modules/core/cs_akick.cpp index 4df83d121..20ceb7c10 100644 --- a/modules/core/cs_akick.cpp +++ b/modules/core/cs_akick.cpp @@ -202,7 +202,9 @@ class CommandCSAKick : public Command * or whether the mask matches a user with higher/equal access - Viper */ if (ci->HasFlag(CI_PEACE) && nc) { - if (nc == ci->founder || get_access_level(ci, nc) >= get_access(u, ci)) + ChanAccess *nc_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u); + int16 nc_level = nc_access ? nc_access->level : 0, u_level = u_access ? u_access->level : 0; + if (nc == ci->founder || nc_level >= u_level) { source.Reply(ACCESS_DENIED); return; @@ -216,7 +218,9 @@ class CommandCSAKick : public Command { User *u2 = *it; - if ((check_access(u2, ci, CA_FOUNDER) || get_access(u2, ci) >= get_access(u, ci)) && match_usermask(mask, u2)) + ChanAccess *u2_access = ci->GetAccess(nc), *u_access = ci->GetAccess(u); + int16 u2_level = u2_access ? u2_access->level : 0, u_level = u_access ? u_access->level : 0; + if ((check_access(u2, ci, CA_FOUNDER) || u2_level >= u_level) && match_usermask(mask, u2)) { source.Reply(ACCESS_DENIED); return; @@ -232,7 +236,9 @@ class CommandCSAKick : public Command if (na2->HasFlag(NS_FORBIDDEN)) continue; - if (na2->nc && (na2->nc == ci->founder || get_access_level(ci, na2->nc) >= get_access(u, ci))) + ChanAccess *na2_access = ci->GetAccess(na2->nc), *u_access = ci->GetAccess(u); + int16 na2_level = na2_access ? na2_access->level : 0, u_level = u_access ? u_access->level : 0; + if (na2->nc && (na2->nc == ci->founder || na2_level >= u_level)) { Anope::string buf = na2->nick + "!" + na2->last_usermask; if (Anope::Match(buf, mask)) diff --git a/modules/core/cs_ban.cpp b/modules/core/cs_ban.cpp index bbcfd1325..a187b5737 100644 --- a/modules/core/cs_ban.cpp +++ b/modules/core/cs_ban.cpp @@ -29,17 +29,19 @@ class CommandCSBan : public Command User *u = source.u; ChannelInfo *ci = source.ci; Channel *c = ci->c; - User *u2; - bool is_same = target.equals_ci(u->nick); + User *u2 = is_same ? u : finduser(target); + + ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2); + uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0; if (!c) source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); - else if (is_same ? !(u2 = u) : !(u2 = finduser(target))) + else if (!u2) source.Reply(NICK_X_NOT_IN_USE, target.c_str()); else if (!is_same ? !check_access(u, ci, CA_BAN) : !check_access(u, ci, CA_BANME)) source.Reply(ACCESS_DENIED); - else if (!is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci))) + else if (!is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level) source.Reply(ACCESS_DENIED); /* * Dont ban/kick the user on channels where he is excepted diff --git a/modules/core/cs_clone.cpp b/modules/core/cs_clone.cpp index b36d75dc5..7eb5fd6bd 100644 --- a/modules/core/cs_clone.cpp +++ b/modules/core/cs_clone.cpp @@ -108,7 +108,7 @@ public: for (unsigned i = 0; i < ci->GetAccessCount(); ++i) { ChanAccess *access = ci->GetAccess(i); - target_ci->AddAccess(access->nc, access->level, access->creator, access->last_seen); + target_ci->AddAccess(access->mask, access->level, access->creator, access->last_seen); } source.Reply(CHAN_CLONED_ACCESS, channel.c_str(), target.c_str()); diff --git a/modules/core/cs_kick.cpp b/modules/core/cs_kick.cpp index 8a2dd8b04..b829ce249 100644 --- a/modules/core/cs_kick.cpp +++ b/modules/core/cs_kick.cpp @@ -29,17 +29,19 @@ class CommandCSKick : public Command User *u = source.u; ChannelInfo *ci = source.ci; Channel *c = ci->c; - User *u2; - bool is_same = target.equals_ci(u->nick); + User *u2 = is_same ? u : finduser(target); + + ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2); + uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0; if (!c) source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); - else if (is_same ? !(u2 = u) : !(u2 = finduser(target))) + else if (!u2) source.Reply(NICK_X_NOT_IN_USE, target.c_str()); else if (!is_same ? !check_access(u, ci, CA_KICK) : !check_access(u, ci, CA_KICKME)) source.Reply(ACCESS_DENIED); - else if (!is_same && (ci->HasFlag(CI_PEACE)) && get_access(u2, ci) >= get_access(u, ci)) + else if (!is_same && (ci->HasFlag(CI_PEACE)) && u2_level >= u_level) source.Reply(ACCESS_DENIED); else if (u2->IsProtected()) source.Reply(ACCESS_DENIED); diff --git a/modules/core/cs_modes.cpp b/modules/core/cs_modes.cpp index 86e1193ef..885b4d81e 100644 --- a/modules/core/cs_modes.cpp +++ b/modules/core/cs_modes.cpp @@ -30,18 +30,20 @@ static CommandReturn do_util(CommandSource &source, Command *com, ChannelMode *c User *u = source.u; Channel *c = findchan(chan); ChannelInfo *ci = c ? c->ci : NULL; - User *u2; - Anope::string realnick = (!nick.empty() ? nick : u->nick); bool is_same = u->nick.equals_ci(realnick); + User *u2 = is_same ? u : finduser(realnick); + + ChanAccess *u_access = ci->GetAccess(u), *u2_access = ci->GetAccess(u2); + uint16 u_level = u_access ? u_access->level : 0, u2_level = u2_access ? u2_access->level : 0; if (!c) source.Reply(CHAN_X_NOT_IN_USE, chan.c_str()); - else if (is_same ? !(u2 = u) : !(u2 = finduser(realnick))) + else if (!u2) source.Reply(NICK_X_NOT_IN_USE, realnick.c_str()); else if (is_same ? !check_access(u, ci, levelself) : !check_access(u, ci, level)) source.Reply(ACCESS_DENIED); - else if (!set && !is_same && (ci->HasFlag(CI_PEACE)) && (get_access(u2, ci) >= get_access(u, ci))) + else if (!set && !is_same && ci->HasFlag(CI_PEACE) && u2_level >= u_level) source.Reply(ACCESS_DENIED); else if (!set && u2->IsProtected() && !is_same) source.Reply(ACCESS_DENIED); diff --git a/modules/core/cs_register.cpp b/modules/core/cs_register.cpp index 39155fe84..db756afa2 100644 --- a/modules/core/cs_register.cpp +++ b/modules/core/cs_register.cpp @@ -28,7 +28,7 @@ class CommandCSRegister : public Command User *u = source.u; ChannelInfo *ci = source.ci; - Channel *c = ci->c; + Channel *c = findchan(chan); if (readonly) { @@ -42,7 +42,7 @@ class CommandCSRegister : public Command source.Reply(CHAN_SYMBOL_REQUIRED); else if (!ircdproto->IsChannelValid(chan)) source.Reply(CHAN_X_INVALID, chan.c_str()); - else if ((ci = cs_findchan(chan))) + else if (ci) source.Reply(CHAN_ALREADY_REGISTERED, chan.c_str()); else if (c && !c->HasUserStatus(u, CMODE_OP)) source.Reply(CHAN_MUST_BE_CHANOP); diff --git a/modules/core/cs_status.cpp b/modules/core/cs_status.cpp index 899632bbf..a2a69b18e 100644 --- a/modules/core/cs_status.cpp +++ b/modules/core/cs_status.cpp @@ -26,8 +26,9 @@ class CommandCSStatus : public Command const Anope::string &nick = params[1]; User *u2 = finduser(nick); + ChanAccess *u2_access = ci->GetAccess(u2); if (u2) - source.Reply(CHAN_STATUS_INFO, ci->name.c_str(), u2->nick.c_str(), get_access(u2, ci)); + source.Reply(CHAN_STATUS_INFO, ci->name.c_str(), u2->nick.c_str(), u2_access ? u2_access->level : 0); else /* !u2 */ source.Reply(CHAN_STATUS_NOTONLINE, nick.c_str()); return MOD_CONT; diff --git a/modules/core/cs_xop.cpp b/modules/core/cs_xop.cpp index 1b15d07fd..f883d1baa 100644 --- a/modules/core/cs_xop.cpp +++ b/modules/core/cs_xop.cpp @@ -26,7 +26,6 @@ enum enum { XOP_DISABLED, - XOP_NICKS_ONLY, XOP_ADDED, XOP_MOVED, XOP_NO_SUCH_ENTRY, @@ -43,7 +42,6 @@ enum LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = { {CHAN_AOP_DISABLED, - CHAN_AOP_NICKS_ONLY, CHAN_AOP_ADDED, CHAN_AOP_MOVED, CHAN_AOP_NO_SUCH_ENTRY, @@ -56,7 +54,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = { CHAN_AOP_LIST_HEADER, CHAN_AOP_CLEAR}, {CHAN_SOP_DISABLED, - CHAN_SOP_NICKS_ONLY, CHAN_SOP_ADDED, CHAN_SOP_MOVED, CHAN_SOP_NO_SUCH_ENTRY, @@ -69,7 +66,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = { CHAN_SOP_LIST_HEADER, CHAN_SOP_CLEAR}, {CHAN_VOP_DISABLED, - CHAN_VOP_NICKS_ONLY, CHAN_VOP_ADDED, CHAN_VOP_MOVED, CHAN_VOP_NO_SUCH_ENTRY, @@ -82,7 +78,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = { CHAN_VOP_LIST_HEADER, CHAN_VOP_CLEAR}, {CHAN_HOP_DISABLED, - CHAN_HOP_NICKS_ONLY, CHAN_HOP_ADDED, CHAN_HOP_MOVED, CHAN_HOP_NO_SUCH_ENTRY, @@ -95,7 +90,6 @@ LanguageString xop_msgs[XOP_TYPES][XOP_MESSAGES] = { CHAN_HOP_LIST_HEADER, CHAN_HOP_CLEAR}, {CHAN_QOP_DISABLED, - CHAN_QOP_NICKS_ONLY, CHAN_QOP_ADDED, CHAN_QOP_MOVED, CHAN_QOP_NO_SUCH_ENTRY, @@ -141,7 +135,7 @@ class XOPListCallback : public NumberList static void DoList(CommandSource &source, ChanAccess *access, unsigned index, int level, LanguageString *messages) { - source.Reply(CHAN_XOP_LIST_FORMAT, index, access->nc->display.c_str()); + source.Reply(CHAN_XOP_LIST_FORMAT, index, access->mask.c_str()); } }; @@ -182,11 +176,11 @@ class XOPDelCallback : public NumberList ++Deleted; if (!Nicks.empty()) - Nicks += ", " + access->nc->display; + Nicks += ", " + access->mask; else - Nicks = access->nc->display; + Nicks = access->mask; - FOREACH_MOD(I_OnAccessDel, OnAccessDel(source.ci, source.u, access->nc)); + FOREACH_MOD(I_OnAccessDel, OnAccessDel(source.ci, source.u, access)); source.ci->EraseAccess(Number - 1); } @@ -200,11 +194,10 @@ class XOPBase : public Command User *u = source.u; ChannelInfo *ci = source.ci; - const Anope::string &nick = params.size() > 2 ? params[2] : ""; - ChanAccess *access; + Anope::string mask = params.size() > 2 ? params[2] : ""; int change = 0; - if (nick.empty()) + if (mask.empty()) { this->OnSyntaxError(source, "ADD"); return MOD_CONT; @@ -216,7 +209,8 @@ class XOPBase : public Command return MOD_CONT; } - short ulev = get_access(u, ci); + ChanAccess *access = ci->GetAccess(u); + uint16 ulev = access ? access->level : 0; if ((level >= ulev || ulev < ACCESS_AOP) && !u->Account()->HasPriv("chanserv/access/modify")) { @@ -224,20 +218,16 @@ class XOPBase : public Command return MOD_CONT; } - NickAlias *na = findnick(nick); - if (!na) - { - source.Reply(messages[XOP_NICKS_ONLY]); - return MOD_CONT; - } - else if (na->HasFlag(NS_FORBIDDEN)) + NickAlias *na = findnick(mask); + if (!na && mask.find_first_of("!@*") == Anope::string::npos) + mask += "!*@*"; + else if (na && na->HasFlag(NS_FORBIDDEN)) { source.Reply(NICK_X_FORBIDDEN, na->nick.c_str()); return MOD_CONT; } - NickCore *nc = na->nc; - access = ci->GetAccess(nc); + access = ci->GetAccess(mask); if (access) { /** @@ -258,7 +248,7 @@ class XOPBase : public Command } if (!change) - ci->AddAccess(nc, level, u->nick); + access = ci->AddAccess(mask, level, u->nick); else { access->level = level; @@ -267,17 +257,17 @@ class XOPBase : public Command } bool override = (level >= ulev || ulev < ACCESS_AOP || (access && access->level > ulev)); - Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << na->nick << " (group: " << nc->display << ") as level " << level; + Log(override ? LOG_OVERRIDE : LOG_COMMAND, u, this, ci) << "ADD " << mask << " as level " << level; if (!change) { - FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, nc, level)); - source.Reply(messages[XOP_ADDED], nc->display.c_str(), ci->name.c_str()); + FOREACH_MOD(I_OnAccessAdd, OnAccessAdd(ci, u, access)); + source.Reply(messages[XOP_ADDED], access->mask.c_str(), ci->name.c_str()); } else { - FOREACH_MOD(I_OnAccessChange, OnAccessChange(ci, u, na->nc, lev |
