1
0
mirror of https://github.com/unrealircd/unrealircd.git synced 2026-07-10 19:43:13 +02:00
Files
unrealircd/src/modules/vhost.c
T
Bram Matthys 3126a3fae4 BIG changes internally that will break all modules and required many
code changes in UnrealIRCd itself:
1) Clients are no longer freed directly by exit_client. Most fields
   are freed, but 'sptr' itself is not, so you can use IsDead() on it.
2) exit_client now returns void rather than int
3) ALL command functions return void rather than int.
   Of course this also affects do_cmd, command overrides, etc.

This is a direct consequence of the removal of 'cptr' earlier, as that
was used to signal certain things that are now no longer possible
(and it raises the question if things were always correctly signaled
in the first place, so may fix some bugs).
It also makes the code more resillient against cases where you forgot
to check if the client was freed. Still, you are encouraged to do an
IsDead(sptr) if you are calling functions that may kill clients,
such as command functions or things that may use spamfilter.

More changes will follow, such as the removal of FLUSH_BUFFER.
2019-10-04 10:28:41 +02:00

173 lines
4.6 KiB
C

/*
* Unreal Internet Relay Chat Daemon, src/modules/vhost.c
* (C) 2000-2001 Carsten V. Munk and the UnrealIRCd Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 1, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "unrealircd.h"
CMD_FUNC(cmd_vhost);
/* Place includes here */
#define MSG_VHOST "VHOST"
ModuleHeader MOD_HEADER
= {
"vhost", /* Name of module */
"5.0", /* Version */
"command /vhost", /* Short description of module */
"UnrealIRCd Team",
"unrealircd-5",
};
/* This is called on module init, before Server Ready */
MOD_INIT()
{
CommandAdd(modinfo->handle, MSG_VHOST, cmd_vhost, MAXPARA, CMD_USER);
MARK_AS_OFFICIAL_MODULE(modinfo);
return MOD_SUCCESS;
}
/* Is first run when server is 100% ready */
MOD_LOAD()
{
return MOD_SUCCESS;
}
/* Called when module is unloaded */
MOD_UNLOAD()
{
return MOD_SUCCESS;
}
CMD_FUNC(cmd_vhost)
{
ConfigItem_vhost *vhost;
char *login, *password;
char olduser[USERLEN+1];
if (!MyUser(sptr))
return;
if ((parc < 2) || BadPtr(parv[1]))
{
sendnumeric(sptr, ERR_NEEDMOREPARAMS, "VHOST");
return;
}
login = parv[1];
password = (parc > 2) ? parv[2] : "";
/* cut-off too long login names. HOSTLEN is arbitrary, we just don't want our
* error messages to be cut off because the user is sending huge login names.
*/
if (strlen(login) > HOSTLEN)
login[HOSTLEN] = '\0';
if (!(vhost = Find_vhost(login)))
{
sendto_snomask(SNO_VHOST,
"[\2vhost\2] Failed login for vhost %s by %s!%s@%s - incorrect password",
login, sptr->name,
sptr->user->username,
sptr->user->realhost);
sendnotice(sptr, "*** [\2vhost\2] Login for %s failed - password incorrect", login);
return;
}
if (!unreal_mask_match(sptr, vhost->mask))
{
sendto_snomask(SNO_VHOST,
"[\2vhost\2] Failed login for vhost %s by %s!%s@%s - host does not match",
login, sptr->name, sptr->user->username, sptr->user->realhost);
sendnotice(sptr, "*** No vHost lines available for your host");
return;
}
if (!Auth_Check(sptr, vhost->auth, password))
{
sendto_snomask(SNO_VHOST,
"[\2vhost\2] Failed login for vhost %s by %s!%s@%s - incorrect password",
login, sptr->name,
sptr->user->username,
sptr->user->realhost);
sendnotice(sptr, "*** [\2vhost\2] Login for %s failed - password incorrect", login);
return;
}
/* Authentication passed, but.. there could still be other restrictions: */
switch (UHOST_ALLOWED)
{
case UHALLOW_NEVER:
if (MyUser(sptr))
{
sendnotice(sptr, "*** /vhost is disabled");
return;
}
break;
case UHALLOW_ALWAYS:
break;
case UHALLOW_NOCHANS:
if (MyUser(sptr) && sptr->user->joined)
{
sendnotice(sptr, "*** /vhost can not be used while you are on a channel");
return;
}
break;
case UHALLOW_REJOIN:
/* join sent later when the host has been changed */
break;
}
/* All checks passed, now let's go ahead and change the host */
userhost_save_current(sptr);
safe_strdup(sptr->user->virthost, vhost->virthost);
if (vhost->virtuser)
{
strcpy(olduser, sptr->user->username);
strlcpy(sptr->user->username, vhost->virtuser, USERLEN);
sendto_server(sptr, 0, 0, NULL, ":%s SETIDENT %s", sptr->name,
sptr->user->username);
}
sptr->umodes |= UMODE_HIDE;
sptr->umodes |= UMODE_SETHOST;
sendto_server(sptr, 0, 0, NULL, ":%s SETHOST %s", sptr->name, sptr->user->virthost);
sendto_one(sptr, NULL, ":%s MODE %s :+tx", sptr->name, sptr->name);
if (vhost->swhois)
{
SWhois *s;
for (s = vhost->swhois; s; s = s->next)
swhois_add(sptr, "vhost", -100, s->line, &me, NULL);
}
sendnumeric(sptr, RPL_HOSTHIDDEN, vhost->virthost);
sendnotice(sptr, "*** Your vhost is now %s%s%s",
vhost->virtuser ? vhost->virtuser : "",
vhost->virtuser ? "@" : "",
vhost->virthost);
sendto_snomask(SNO_VHOST,
"[\2vhost\2] %s (%s!%s@%s) is now using vhost %s%s%s",
login, sptr->name,
vhost->virtuser ? olduser : sptr->user->username,
sptr->user->realhost, vhost->virtuser ? vhost->virtuser : "",
vhost->virtuser ? "@" : "", vhost->virthost);
userhost_changed(sptr);
}