1 /*
2  *
3  * (C) 2003-2020 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 "services.h"
13 #include "account.h"
14 #include "modules.h"
15 #include "opertype.h"
16 #include "protocol.h"
17 #include "users.h"
18 #include "servers.h"
19 #include "config.h"
20 
21 Serialize::Checker<nickalias_map> NickAliasList("NickAlias");
22 
NickAlias(const Anope::string & nickname,NickCore * nickcore)23 NickAlias::NickAlias(const Anope::string &nickname, NickCore* nickcore) : Serializable("NickAlias")
24 {
25 	if (nickname.empty())
26 		throw CoreException("Empty nick passed to NickAlias constructor");
27 	else if (!nickcore)
28 		throw CoreException("Empty nickcore passed to NickAlias constructor");
29 
30 	this->time_registered = this->last_seen = Anope::CurTime;
31 	this->nick = nickname;
32 	this->nc = nickcore;
33 	nickcore->aliases->push_back(this);
34 
35 	size_t old = NickAliasList->size();
36 	(*NickAliasList)[this->nick] = this;
37 	if (old == NickAliasList->size())
38 		Log(LOG_DEBUG) << "Duplicate nick " << nickname << " in nickalias table";
39 
40 	if (this->nc->o == NULL)
41 	{
42 		Oper *o = Oper::Find(this->nick);
43 		if (o == NULL)
44 			o = Oper::Find(this->nc->display);
45 		nickcore->o = o;
46 		if (this->nc->o != NULL)
47 			Log() << "Tied oper " << this->nc->display << " to type " << this->nc->o->ot->GetName();
48 	}
49 }
50 
~NickAlias()51 NickAlias::~NickAlias()
52 {
53 	FOREACH_MOD(OnDelNick, (this));
54 
55 	UnsetExtensibles();
56 
57 	/* Accept nicks that have no core, because of database load functions */
58 	if (this->nc)
59 	{
60 		/* Next: see if our core is still useful. */
61 		std::vector<NickAlias *>::iterator it = std::find(this->nc->aliases->begin(), this->nc->aliases->end(), this);
62 		if (it != this->nc->aliases->end())
63 			this->nc->aliases->erase(it);
64 		if (this->nc->aliases->empty())
65 		{
66 			delete this->nc;
67 			this->nc = NULL;
68 		}
69 		else
70 		{
71 			/* Display updating stuff */
72 			if (this->nick.equals_ci(this->nc->display))
73 				this->nc->SetDisplay(this->nc->aliases->front());
74 		}
75 	}
76 
77 	/* Remove us from the aliases list */
78 	NickAliasList->erase(this->nick);
79 }
80 
SetVhost(const Anope::string & ident,const Anope::string & host,const Anope::string & creator,time_t created)81 void NickAlias::SetVhost(const Anope::string &ident, const Anope::string &host, const Anope::string &creator, time_t created)
82 {
83 	this->vhost_ident = ident;
84 	this->vhost_host = host;
85 	this->vhost_creator = creator;
86 	this->vhost_created = created;
87 }
88 
RemoveVhost()89 void NickAlias::RemoveVhost()
90 {
91 	this->vhost_ident.clear();
92 	this->vhost_host.clear();
93 	this->vhost_creator.clear();
94 	this->vhost_created = 0;
95 }
96 
HasVhost() const97 bool NickAlias::HasVhost() const
98 {
99 	return !this->vhost_host.empty();
100 }
101 
GetVhostIdent() const102 const Anope::string &NickAlias::GetVhostIdent() const
103 {
104 	return this->vhost_ident;
105 }
106 
GetVhostHost() const107 const Anope::string &NickAlias::GetVhostHost() const
108 {
109 	return this->vhost_host;
110 }
111 
GetVhostCreator() const112 const Anope::string &NickAlias::GetVhostCreator() const
113 {
114 	return this->vhost_creator;
115 }
116 
GetVhostCreated() const117 time_t NickAlias::GetVhostCreated() const
118 {
119 	return this->vhost_created;
120 }
121 
Find(const Anope::string & nick)122 NickAlias *NickAlias::Find(const Anope::string &nick)
123 {
124 	nickalias_map::const_iterator it = NickAliasList->find(nick);
125 	if (it != NickAliasList->end())
126 	{
127 		it->second->QueueUpdate();
128 		return it->second;
129 	}
130 
131 	return NULL;
132 }
133 
Serialize(Serialize::Data & data) const134 void NickAlias::Serialize(Serialize::Data &data) const
135 {
136 	data["nick"] << this->nick;
137 	data["last_quit"] << this->last_quit;
138 	data["last_realname"] << this->last_realname;
139 	data["last_usermask"] << this->last_usermask;
140 	data["last_realhost"] << this->last_realhost;
141 	data.SetType("time_registered", Serialize::Data::DT_INT); data["time_registered"] << this->time_registered;
142 	data.SetType("last_seen", Serialize::Data::DT_INT); data["last_seen"] << this->last_seen;
143 	data["nc"] << this->nc->display;
144 
145 	if (this->HasVhost())
146 	{
147 		data["vhost_ident"] << this->GetVhostIdent();
148 		data["vhost_host"] << this->GetVhostHost();
149 		data["vhost_creator"] << this->GetVhostCreator();
150 		data["vhost_time"] << this->GetVhostCreated();
151 	}
152 
153 	Extensible::ExtensibleSerialize(this, this, data);
154 }
155 
Unserialize(Serializable * obj,Serialize::Data & data)156 Serializable* NickAlias::Unserialize(Serializable *obj, Serialize::Data &data)
157 {
158 	Anope::string snc, snick;
159 
160 	data["nc"] >> snc;
161 	data["nick"] >> snick;
162 
163 	NickCore *core = NickCore::Find(snc);
164 	if (core == NULL)
165 		return NULL;
166 
167 	NickAlias *na;
168 	if (obj)
169 		na = anope_dynamic_static_cast<NickAlias *>(obj);
170 	else
171 		na = new NickAlias(snick, core);
172 
173 	if (na->nc != core)
174 	{
175 		std::vector<NickAlias *>::iterator it = std::find(na->nc->aliases->begin(), na->nc->aliases->end(), na);
176 		if (it != na->nc->aliases->end())
177 			na->nc->aliases->erase(it);
178 
179 		if (na->nc->aliases->empty())
180 			delete na->nc;
181 		else if (na->nick.equals_ci(na->nc->display))
182 			na->nc->SetDisplay(na->nc->aliases->front());
183 
184 		na->nc = core;
185 		core->aliases->push_back(na);
186 	}
187 
188 	data["last_quit"] >> na->last_quit;
189 	data["last_realname"] >> na->last_realname;
190 	data["last_usermask"] >> na->last_usermask;
191 	data["last_realhost"] >> na->last_realhost;
192 	data["time_registered"] >> na->time_registered;
193 	data["last_seen"] >> na->last_seen;
194 
195 	Anope::string vhost_ident, vhost_host, vhost_creator;
196 	time_t vhost_time;
197 
198 	data["vhost_ident"] >> vhost_ident;
199 	data["vhost_host"] >> vhost_host;
200 	data["vhost_creator"] >> vhost_creator;
201 	data["vhost_time"] >> vhost_time;
202 
203 	na->SetVhost(vhost_ident, vhost_host, vhost_creator, vhost_time);
204 
205 	Extensible::ExtensibleUnserialize(na, na, data);
206 
207 	/* compat */
208 	bool b;
209 	b = false;
210 	data["extensible:NO_EXPIRE"] >> b;
211 	if (b)
212 		na->Extend<bool>("NS_NO_EXPIRE");
213 	/* end compat */
214 
215 	return na;
216 }
217