anope

- supernets anope source code & configuration
git clone git://git.acid.vegas/anope.git
Log | Files | Refs | Archive | README

ns_access.cpp (5870B)

      1 /* NickServ 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 class CommandNSAccess : public Command
     15 {
     16  private:
     17 	void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &mask)
     18 	{
     19 		if (mask.empty())
     20 		{
     21 			this->OnSyntaxError(source, "ADD");
     22 			return;
     23 		}
     24 
     25 		if (Anope::ReadOnly)
     26 		{
     27 			source.Reply(READ_ONLY_MODE);
     28 			return;
     29 		}
     30 
     31 		if (nc->access.size() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax", "32"))
     32 		{
     33 			source.Reply(_("Sorry, the maximum of %d access entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
     34 			return;
     35 		}
     36 
     37 		if (nc->FindAccess(mask))
     38 		{
     39 			source.Reply(_("Mask \002%s\002 already present on %s's access list."), mask.c_str(), nc->display.c_str());
     40 			return;
     41 		}
     42 
     43 		nc->AddAccess(mask);
     44 		Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD mask " << mask << " to " << nc->display;
     45 		source.Reply(_("\002%s\002 added to %s's access list."), mask.c_str(), nc->display.c_str());
     46 
     47 		return;
     48 	}
     49 
     50 	void DoDel(CommandSource &source, NickCore *nc, const Anope::string &mask)
     51 	{
     52 		if (mask.empty())
     53 		{
     54 			this->OnSyntaxError(source, "DEL");
     55 			return;
     56 		}
     57 
     58 		if (Anope::ReadOnly)
     59 		{
     60 			source.Reply(READ_ONLY_MODE);
     61 			return;
     62 		}
     63 
     64 		if (!nc->FindAccess(mask))
     65 		{
     66 			source.Reply(_("\002%s\002 not found on %s's access list."), mask.c_str(), nc->display.c_str());
     67 			return;
     68 		}
     69 
     70 		nc->EraseAccess(mask);
     71 		Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to DELETE mask " << mask << " from " << nc->display;
     72 		source.Reply(_("\002%s\002 deleted from %s's access list."), mask.c_str(), nc->display.c_str());
     73 
     74 		return;
     75 	}
     76 
     77 	void DoList(CommandSource &source, NickCore *nc, const Anope::string &mask)
     78 	{
     79 		unsigned i, end;
     80 
     81 		if (nc->access.empty())
     82 		{
     83 			source.Reply(_("%s's access list is empty."), nc->display.c_str());
     84 			return;
     85 		}
     86 
     87 		source.Reply(_("Access list for %s:"), nc->display.c_str());
     88 		for (i = 0, end = nc->access.size(); i < end; ++i)
     89 		{
     90 			Anope::string access = nc->GetAccess(i);
     91 			if (!mask.empty() && !Anope::Match(access, mask))
     92 				continue;
     93 			source.Reply("    %s", access.c_str());
     94 		}
     95 
     96 		return;
     97 	}
     98  public:
     99 	CommandNSAccess(Module *creator) : Command(creator, "nickserv/access", 1, 3)
    100 	{
    101 		this->SetDesc(_("Modify the list of authorized addresses"));
    102 		this->SetSyntax(_("ADD [\037nickname\037] \037mask\037"));
    103 		this->SetSyntax(_("DEL [\037nickname\037] \037mask\037"));
    104 		this->SetSyntax(_("LIST [\037nickname\037]"));
    105 	}
    106 
    107 	void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
    108 	{
    109 		const Anope::string &cmd = params[0];
    110 		Anope::string nick, mask;
    111 
    112 		if (cmd.equals_ci("LIST"))
    113 			nick = params.size() > 1 ? params[1] : "";
    114 		else
    115 		{
    116 			nick = params.size() == 3 ? params[1] : "";
    117 			mask = params.size() > 1 ? params[params.size() - 1] : "";
    118 		}
    119 
    120 		NickCore *nc;
    121 		if (!nick.empty())
    122 		{
    123 			const NickAlias *na = NickAlias::Find(nick);
    124 			if (na == NULL)
    125 			{
    126 				source.Reply(NICK_X_NOT_REGISTERED, nick.c_str());
    127 				return;
    128 			}
    129 			else if (na->nc != source.GetAccount() && !source.HasPriv("nickserv/access"))
    130 			{
    131 				source.Reply(ACCESS_DENIED);
    132 				return;
    133 			}
    134 			else if (Config->GetModule("nickserv")->Get<bool>("secureadmins", "yes") && source.GetAccount() != na->nc && na->nc->IsServicesOper() && !cmd.equals_ci("LIST"))
    135 			{
    136 				source.Reply(_("You may view but not modify the access list of other Services Operators."));
    137 				return;
    138 			}
    139 
    140 			nc = na->nc;
    141 		}
    142 		else
    143 			nc = source.nc;
    144 
    145 		if (!mask.empty() && (mask.find('@') == Anope::string::npos || mask.find('!') != Anope::string::npos))
    146 		{
    147 			source.Reply(BAD_USERHOST_MASK);
    148 			source.Reply(MORE_INFO, Config->StrictPrivmsg.c_str(), source.service->nick.c_str(), source.command.c_str());
    149 		}
    150 		else if (cmd.equals_ci("LIST"))
    151 			return this->DoList(source, nc, mask);
    152 		else if (nc->HasExt("NS_SUSPENDED"))
    153 			source.Reply(NICK_X_SUSPENDED, nc->display.c_str());
    154 		else if (cmd.equals_ci("ADD"))
    155 			return this->DoAdd(source, nc, mask);
    156 		else if (cmd.equals_ci("DEL"))
    157 			return this->DoDel(source, nc, mask);
    158 		else
    159 			this->OnSyntaxError(source, "");
    160 	}
    161 
    162 	bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
    163 	{
    164 		this->SendSyntax(source);
    165 		source.Reply(" ");
    166 		source.Reply(_("Modifies or displays the access list for your nick.  This\n"
    167 					"is the list of addresses which will be automatically\n"
    168 					"recognized by %s as allowed to use the nick.  If\n"
    169 					"you want to use the nick from a different address, you\n"
    170 					"need to send an \002IDENTIFY\002 command to make %s\n"
    171 					"recognize you. Services Operators may provide a nick\n"
    172 					"to modify other users' access lists.\n"
    173 					" \n"
    174 					"Examples:\n"
    175 					" \n"
    176 					"    \002ACCESS ADD anyone@*.bepeg.com\002\n"
    177 					"        Allows access to user \002anyone\002 from any machine in\n"
    178 					"        the \002bepeg.com\002 domain.\n"
    179 					" \n"
    180 					"    \002ACCESS DEL anyone@*.bepeg.com\002\n"
    181 					"        Reverses the previous command.\n"
    182 					" \n"
    183 					"    \002ACCESS LIST\002\n"
    184 					"        Displays the current access list."), source.service->nick.c_str(), source.service->nick.c_str());
    185 		return true;
    186 	}
    187 };
    188 
    189 class NSAccess : public Module
    190 {
    191 	CommandNSAccess commandnsaccess;
    192 
    193  public:
    194 	NSAccess(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
    195 		commandnsaccess(this)
    196 	{
    197 	}
    198 
    199 	void OnNickRegister(User *u, NickAlias *na, const Anope::string &) anope_override
    200 	{
    201 		if (u && Config->GetModule(this)->Get<bool>("addaccessonreg"))
    202 			na->nc->AddAccess(u->Mask());
    203 	}
    204 };
    205 
    206 MODULE_INIT(NSAccess)