Our server pr0vider carried out maintenance on 15 January 2020 but it corrupted some files in the process. If you notice anything out of the ordinary (partial files, pages not loading, that kind of shit) then let us know at:

Browse Source

ns_sagroup: Because in some cases (like external auth DBs) opers cannot use the regular '/ns group' command, we now also allow them to only add/remove _non-oper/unregged nicks_ into/from _their own group_ =]]

Wazakindjes 1 year ago
parent
commit
d4dd025478
2 changed files with 70 additions and 28 deletions
  1. 3 0
      README.md
  2. 67 28
      a2/ns_sagroup.cpp

+ 3 - 0
README.md

@@ -25,6 +25,9 @@ This README contains all modules and their descriptions/usage info (ordered from
 # ns_sagroup
 Requested by `Mi_92`, this module allows services operators/admins to group/ungroup nicknames on behalf of others. You cannot use this to change groups related to operators/admins, they have to use regular `/ns GROUP` commands themselves. It abides by the same rules as `REGISTER` for nicknames and shit. ;]
 
+__Updated shit:__
+* Because in some cases (like external auth DBs) __opers__ cannot use the regular `/ns group` command, we now also allow them to only add/remove __their own/unregged nicks__ into/from __their own group__ =]]
+
 __Usage:__
 Edit your `nickserv.conf` so it contains the following:
     module {

+ 67 - 28
a2/ns_sagroup.cpp

@@ -1,7 +1,7 @@
 #include "module.h"
 
 #define AUTHOR "Gottem"
-#define VERSION "1.0"
+#define VERSION "1.1"
 #define INVALID_NICKNAME "This nickname is invalid for use with standard RFC 2812"
 
 class CommandNSSaGroup : public Command {
@@ -11,37 +11,39 @@ class CommandNSSaGroup : public Command {
 		void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override {
 			const Anope::string &nick = params[0];
 			const Anope::string &target = params[1];
-			size_t nicklen = nick.length();
-			NickAlias *na, *natarget;
+			const Anope::string &guestnick = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
+			size_t nicklen;
+			unsigned maxaliases, i;
+			Anope::string last_uhmask, last_gecos;
+			NickCore *ncsource;
+			NickAlias *na, *natarget, *nasource;
+			Oper *sourceOper, *o;
+			bool nickOper, targetOper;
+			User *u;
 
 			if(Anope::ReadOnly) {
 				source.Reply(_("Sorry, nickname grouping is temporarily disabled."));
 				return;
 			}
-
 			if(!IRCD->IsNickValid(nick)) {
 				source.Reply(NICK_CANNOT_BE_REGISTERED, nick.c_str());
 				return;
 			}
-
 			if(BotInfo::Find(nick, true)) {
 				source.Reply(NICK_CANNOT_BE_REGISTERED, nick.c_str());
 				return;
 			}
-
 			if(isdigit(nick[0]) || nick[0] == '-') {
 				source.Reply(INVALID_NICKNAME);
 				return;
 			}
 
-			const Anope::string &guestnick = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
+			nicklen = nick.length();
 			if(nicklen <= guestnick.length() + 7 && nicklen >= guestnick.length() + 1 && !nick.find_ci(guestnick) && nick.substr(guestnick.length()).find_first_not_of("1234567890") == Anope::string::npos) {
 				source.Reply(NICK_CANNOT_BE_REGISTERED, nick.c_str());
 				return;
 			}
 
-			na = NickAlias::Find(nick);
-			unsigned maxaliases = Config->GetModule(this->owner)->Get<unsigned>("maxaliases");
 			if(!(natarget = NickAlias::Find(target)) || !natarget->nc) {
 				source.Reply(NICK_X_NOT_REGISTERED, target.c_str());
 				return;
@@ -50,26 +52,37 @@ class CommandNSSaGroup : public Command {
 				source.Reply(NICK_X_SUSPENDED, natarget->nick.c_str());
 				return;
 			}
-			if(na && *natarget->nc == *na->nc) {
+			if((na = NickAlias::Find(nick)) && *natarget->nc == *na->nc) {
 				source.Reply(_("That nick (\002%s\002) is already a member of that group (\002%s\002)"), nick.c_str(), natarget->nick.c_str());
 				return;
 			}
-			if(maxaliases && natarget->nc->aliases->size() >= maxaliases) {
+			if((maxaliases = Config->GetModule(this->owner)->Get<unsigned>("maxaliases")) && natarget->nc->aliases->size() >= maxaliases) {
 				source.Reply(_("There are too many nicks in that group (%d >= %d)"), natarget->nc->aliases->size(), maxaliases);
 				return;
 			}
 
-			for(unsigned i = 0; i < Oper::opers.size(); ++i) {
-				Oper *o = Oper::opers[i];
-				if((na && na->nick.find_ci(o->name) != Anope::string::npos) || (!na && nick.find_ci(o->name) != Anope::string::npos) || natarget->nick.find_ci(o->name) != Anope::string::npos) {
-					source.Reply(_("You cannot use this command to change an operator's group"));
+			ncsource = source.GetAccount();
+			sourceOper = NULL;
+			if(ncsource) {
+				nasource = NickAlias::Find(source.GetNick());
+				if(nasource)
+					sourceOper = Oper::Find(nasource->nick);
+				if(!sourceOper)
+					sourceOper = Oper::Find(ncsource->display);
+			}
+			for(i = 0; i < Oper::opers.size(); ++i) {
+				o = Oper::opers[i];
+				nickOper = ((na && na->nick.find_ci(o->name) != Anope::string::npos) || (!na && nick.find_ci(o->name) != Anope::string::npos));
+				targetOper = (natarget->nick.find_ci(o->name) != Anope::string::npos);
+				if((nickOper && sourceOper != o) || (targetOper && sourceOper != o)) {
+					source.Reply(_("You cannot use this command to change an operator's group (except your own)"));
 					return;
 				}
 			}
 
-			Anope::string last_uhmask = "*@*";
-			Anope::string last_gecos = "unknown";
-			User *u = User::Find(nick, true);
+			last_uhmask = "*@*";
+			last_gecos = "unknown";
+			u = User::Find(nick, true);
 			if(u) {
 				last_uhmask = u->GetIdent() + "@" + u->GetDisplayedHost();
 				last_gecos = u->realname;
@@ -96,7 +109,12 @@ class CommandNSSaGroup : public Command {
 
 		bool OnHelp(CommandSource &source, const Anope::string &subcommand) {
 			source.Reply(_("Syntax: \2SAGROUP \37nick\37 \37target\37"));
-			source.Reply(_("Allows services admins to make other nicknames join a group"));
+			source.Reply(_("Allows services admins to make other nicknames join an existing"));
+			source.Reply(_("nick group (\37target\37)."));
+			source.Reply(_(" "));
+			source.Reply(_("It is recommended to use this command with a non-registered"));
+			source.Reply(_("\37nick\37 because it will be registered automatically when"));
+			source.Reply(_("using this command."));
 			return true;
 		}
 
@@ -115,14 +133,18 @@ class CommandNSSaUngroup : public Command {
 
 		void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override {
 			const Anope::string &nick = params[0];
-			NickAlias *na;
+			NickAlias *na, *nasource;
+			NickCore *nc, *oldcore, *ncsource;
+			Oper *sourceOper, *o;
+			bool nickOper, targetOper;
+			unsigned i;
+			User *u;
 
 			if(Anope::ReadOnly) {
 				source.Reply(_("Sorry, nickname grouping is temporarily disabled."));
 				return;
 			}
-
-			if(!(na = NickAlias::Find(nick))) {
+			if(!(na = NickAlias::Find(nick)) || !na->nc) {
 				source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
 				return;
 			}
@@ -131,30 +153,47 @@ class CommandNSSaUngroup : public Command {
 				return;
 			}
 
-			NickCore *oldcore = na->nc;
+			oldcore = na->nc;
+
+			ncsource = source.GetAccount();
+			sourceOper = NULL;
+			if(ncsource) {
+				nasource = NickAlias::Find(source.GetNick());
+				if(nasource)
+					sourceOper = Oper::Find(nasource->nick);
+				if(!sourceOper)
+					sourceOper = Oper::Find(ncsource->display);
+			}
+			for(i = 0; i < Oper::opers.size(); ++i) {
+				o = Oper::opers[i];
+				nickOper = (na->nick.find_ci(o->name) != Anope::string::npos);
+				targetOper = (oldcore->display.find_ci(o->name) != Anope::string::npos);
+				if((nickOper && sourceOper != o) || (targetOper && sourceOper != o)) {
+					source.Reply(_("You cannot use this command to change an operator's group (except your own)"));
+					return;
+				}
+			}
 
 			std::vector<NickAlias *>::iterator it = std::find(oldcore->aliases->begin(), oldcore->aliases->end(), na);
 			if(it != oldcore->aliases->end())
 				oldcore->aliases->erase(it);
-
 			if(na->nick.equals_ci(oldcore->display))
 				oldcore->SetDisplay(oldcore->aliases->front());
 
-			NickCore *nc = new NickCore(na->nick);
+			nc = new NickCore(na->nick);
 			na->nc = nc;
 			nc->aliases->push_back(na);
-
 			nc->pass = oldcore->pass;
 			if(!oldcore->email.empty())
 				nc->email = oldcore->email;
 				nc->language = oldcore->language;
 
-			User *u = User::Find(na->nick, true);
+			u = User::Find(na->nick, true);
 			if(u)
 				u->Login(nc);
 
 			Log(LOG_COMMAND, source, this) << "to make " << nick << " leave group of " << oldcore->display;
-			source.Reply(_("Nick %s has been ungrouped from %s."), na->nick.c_str(), oldcore->display.c_str());
+			source.Reply(_("Nick \2%s\2 has been ungrouped from \2%s\2"), na->nick.c_str(), oldcore->display.c_str());
 		}
 
 		bool OnHelp(CommandSource &source, const Anope::string &subcommand) {