]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_nicklock.cpp
Merge the latest changes from insp20 into master.
[user/henk/code/inspircd.git] / src / modules / m_nicklock.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007, 2009 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
7  *   Copyright (C) 2005-2006 Craig Edwards <craigedwards@brainbox.cc>
8  *
9  * This file is part of InspIRCd.  InspIRCd is free software: you can
10  * redistribute it and/or modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation, version 2.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #include "inspircd.h"
24
25 enum
26 {
27         // InspIRCd-specific.
28         ERR_NICKNOTLOCKED = 946,
29         RPL_NICKLOCKON = 947,
30         RPL_NICKLOCKOFF = 945
31 };
32
33 /** Handle /NICKLOCK
34  */
35 class CommandNicklock : public Command
36 {
37  public:
38         LocalIntExt& locked;
39         CommandNicklock (Module* Creator, LocalIntExt& ext) : Command(Creator,"NICKLOCK", 2),
40                 locked(ext)
41         {
42                 flags_needed = 'o';
43                 syntax = "<oldnick> <newnick>";
44                 TRANSLATE2(TR_NICK, TR_TEXT);
45         }
46
47         CmdResult Handle(const std::vector<std::string>& parameters, User *user)
48         {
49                 User* target = ServerInstance->FindNick(parameters[0]);
50
51                 if ((!target) || (target->registered != REG_ALL))
52                 {
53                         user->WriteNotice("*** No such nickname: '" + parameters[0] + "'");
54                         return CMD_FAILURE;
55                 }
56
57                 /* Do local sanity checks and bails */
58                 if (IS_LOCAL(user))
59                 {
60                         if (!ServerInstance->IsNick(parameters[1]))
61                         {
62                                 user->WriteNotice("*** Invalid nickname '" + parameters[1] + "'");
63                                 return CMD_FAILURE;
64                         }
65
66                         user->WriteNumeric(RPL_NICKLOCKON, parameters[1], "Nickname now locked.");
67                 }
68
69                 /* If we made it this far, extend the user */
70                 if (IS_LOCAL(target))
71                 {
72                         locked.set(target, 1);
73
74                         std::string oldnick = target->nick;
75                         if (target->ChangeNick(parameters[1]))
76                                 ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used NICKLOCK to change and hold "+oldnick+" to "+parameters[1]);
77                         else
78                         {
79                                 std::string newnick = target->nick;
80                                 ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used NICKLOCK, but "+oldnick+" failed nick change to "+parameters[1]+" and was locked to "+newnick+" instead");
81                         }
82                 }
83
84                 return CMD_SUCCESS;
85         }
86
87         RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
88         {
89                 return ROUTE_OPT_UCAST(parameters[0]);
90         }
91 };
92
93 /** Handle /NICKUNLOCK
94  */
95 class CommandNickunlock : public Command
96 {
97  public:
98         LocalIntExt& locked;
99         CommandNickunlock (Module* Creator, LocalIntExt& ext) : Command(Creator,"NICKUNLOCK", 1),
100                 locked(ext)
101         {
102                 flags_needed = 'o';
103                 syntax = "<locked-nick>";
104                 TRANSLATE1(TR_NICK);
105         }
106
107         CmdResult Handle (const std::vector<std::string>& parameters, User *user)
108         {
109                 User* target = ServerInstance->FindNick(parameters[0]);
110
111                 if (!target)
112                 {
113                         user->WriteNotice("*** No such nickname: '" + parameters[0] + "'");
114                         return CMD_FAILURE;
115                 }
116
117                 if (IS_LOCAL(target))
118                 {
119                         if (locked.set(target, 0))
120                         {
121                                 ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used NICKUNLOCK on "+target->nick);
122                                 user->WriteRemoteNumeric(RPL_NICKLOCKOFF, target->nick, "Nickname now unlocked.");
123                         }
124                         else
125                         {
126                                 user->WriteRemoteNumeric(ERR_NICKNOTLOCKED, target->nick, "This user's nickname is not locked.");
127                                 return CMD_FAILURE;
128                         }
129                 }
130
131                 return CMD_SUCCESS;
132         }
133
134         RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
135         {
136                 return ROUTE_OPT_UCAST(parameters[0]);
137         }
138 };
139
140 class ModuleNickLock : public Module
141 {
142         LocalIntExt locked;
143         CommandNicklock cmd1;
144         CommandNickunlock cmd2;
145  public:
146         ModuleNickLock()
147                 : locked("nick_locked", ExtensionItem::EXT_USER, this)
148                 , cmd1(this, locked)
149                 , cmd2(this, locked)
150         {
151         }
152
153         Version GetVersion() CXX11_OVERRIDE
154         {
155                 return Version("Provides the NICKLOCK command, allows an oper to change a users nick and lock them to it until they quit", VF_OPTCOMMON | VF_VENDOR);
156         }
157
158         ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) CXX11_OVERRIDE
159         {
160                 if (locked.get(user))
161                 {
162                         user->WriteNumeric(ERR_CANTCHANGENICK, "You cannot change your nickname (your nick is locked)");
163                         return MOD_RES_DENY;
164                 }
165                 return MOD_RES_PASSTHRU;
166         }
167
168         void Prioritize() CXX11_OVERRIDE
169         {
170                 Module *nflood = ServerInstance->Modules->Find("m_nickflood.so");
171                 ServerInstance->Modules->SetPriority(this, I_OnUserPreNick, PRIORITY_BEFORE, nflood);
172         }
173 };
174
175 MODULE_INIT(ModuleNickLock)