mirror of
https://github.com/unrealircd/unrealircd.git
synced 2026-07-04 19:23:13 +02:00
1112 lines
24 KiB
C
1112 lines
24 KiB
C
/*
|
|
* Unreal Internet Relay Chat Daemon, src/s_svs.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 "struct.h"
|
|
#include "common.h"
|
|
#include "sys.h"
|
|
#include "numeric.h"
|
|
#include "channel.h"
|
|
#include <fcntl.h>
|
|
#ifndef _WIN32
|
|
#include <sys/socket.h>
|
|
#include <sys/wait.h>
|
|
#else
|
|
#include <io.h>
|
|
#endif
|
|
#include <sys/stat.h>
|
|
#ifdef __hpux
|
|
#include "inet.h"
|
|
#endif
|
|
#if defined(PCS) || defined(AIX) || defined(SVR3)
|
|
#include <time.h>
|
|
#endif
|
|
#include <string.h>
|
|
|
|
#include "h.h"
|
|
|
|
extern int SVSNOOP;
|
|
extern ircstats IRCstats;
|
|
|
|
#define STAR1 OFLAG_SADMIN|OFLAG_ADMIN|OFLAG_NETADMIN|OFLAG_COADMIN
|
|
#define STAR2 OFLAG_TECHADMIN|OFLAG_ZLINE|OFLAG_HIDE|OFLAG_WHOIS
|
|
#define STAR3 OFLAG_INVISIBLE
|
|
|
|
int oper_access[] = {
|
|
~(STAR1 | STAR2 | STAR3), '*',
|
|
OFLAG_LOCAL, 'o',
|
|
OFLAG_GLOBAL, 'O',
|
|
OFLAG_REHASH, 'r',
|
|
OFLAG_EYES, 'e',
|
|
OFLAG_DIE, 'D',
|
|
OFLAG_RESTART, 'R',
|
|
OFLAG_HELPOP, 'h',
|
|
OFLAG_GLOBOP, 'g',
|
|
OFLAG_WALLOP, 'w',
|
|
OFLAG_LOCOP, 'l',
|
|
OFLAG_LROUTE, 'c',
|
|
OFLAG_GROUTE, 'L',
|
|
OFLAG_LKILL, 'k',
|
|
OFLAG_GKILL, 'K',
|
|
OFLAG_KLINE, 'b',
|
|
OFLAG_UNKLINE, 'B',
|
|
OFLAG_LNOTICE, 'n',
|
|
OFLAG_GNOTICE, 'G',
|
|
OFLAG_ADMIN, 'A',
|
|
OFLAG_SADMIN, 'a',
|
|
OFLAG_NETADMIN, 'N',
|
|
OFLAG_COADMIN, 'C',
|
|
OFLAG_TECHADMIN, 'T',
|
|
OFLAG_UMODEC, 'u',
|
|
OFLAG_UMODEF, 'f',
|
|
OFLAG_ZLINE, 'z',
|
|
OFLAG_WHOIS, 'W',
|
|
OFLAG_HIDE, 'H',
|
|
OFLAG_INVISIBLE, '^',
|
|
0, 0
|
|
};
|
|
|
|
char oflagbuf[128];
|
|
|
|
char *oflagstr(long oflag)
|
|
{
|
|
int *i, flag;
|
|
char m;
|
|
char *p = oflagbuf;
|
|
|
|
for (i = &oper_access[6], m = *(i + 1); (flag = *i);
|
|
i += 2, m = *(i + 1))
|
|
{
|
|
if (oflag & flag)
|
|
{
|
|
*p = m;
|
|
p++;
|
|
}
|
|
}
|
|
*p = '\0';
|
|
return oflagbuf;
|
|
}
|
|
|
|
/* ok, given a mask, our job is to determine
|
|
* wether or not it's a safe mask to banish...
|
|
*
|
|
* userhost= mask to verify
|
|
* ipstat= TRUE == it's an ip
|
|
* FALSE == it's a hostname
|
|
* UNSURE == we need to find out
|
|
* return value
|
|
* TRUE == mask is ok
|
|
* FALSE == mask is not ok
|
|
* UNSURE == [unused] something went wrong
|
|
*/
|
|
|
|
int advanced_check(char *userhost, int ipstat)
|
|
{
|
|
register int retval = TRUE;
|
|
char *up, *p, *thisseg;
|
|
int numdots = 0, segno = 0, numseg, i = 0;
|
|
char *ipseg[10 + 2];
|
|
char safebuffer[512] = ""; /* buffer strtoken() can mess up to its heart's content...;> */
|
|
|
|
strcpy(safebuffer, userhost);
|
|
|
|
#define userhost safebuffer
|
|
#define IP_WILDS_OK(x) ((x)<2? 0 : 1)
|
|
|
|
if (ipstat == UNSURE)
|
|
{
|
|
ipstat = TRUE;
|
|
for (; *up; up++)
|
|
{
|
|
if (*up == '.')
|
|
numdots++;
|
|
if (!isdigit(*up) && !ispunct(*up))
|
|
{
|
|
ipstat = FALSE;
|
|
continue;
|
|
}
|
|
}
|
|
if (numdots != 3)
|
|
ipstat = FALSE;
|
|
if (numdots < 1 || numdots > 9)
|
|
return (0);
|
|
}
|
|
|
|
/* fill in the segment set */
|
|
{
|
|
int l = 0;
|
|
for (segno = 0, i = 0, thisseg = strtoken(&p, userhost, ".");
|
|
thisseg; thisseg = strtoken(&p, NULL, "."), i++)
|
|
{
|
|
|
|
l = strlen(thisseg) + 2;
|
|
ipseg[segno] = calloc(1, l);
|
|
strncpy(ipseg[segno++], thisseg, l);
|
|
}
|
|
}
|
|
if (segno < 2 && ipstat == TRUE)
|
|
retval = FALSE;
|
|
numseg = segno;
|
|
if (ipstat == TRUE)
|
|
for (i = 0; i < numseg; i++)
|
|
{
|
|
if (!IP_WILDS_OK(i) && index(ipseg[i], '*')
|
|
|| index(ipseg[i], '?'))
|
|
retval = FALSE;
|
|
/* The person who wrote this function was braindead --Stskeeps */
|
|
/* MyFree(ipseg[i]); */
|
|
}
|
|
else
|
|
{
|
|
int wildsok = 0;
|
|
|
|
for (i = 0; i < numseg; i++)
|
|
{
|
|
/* for hosts, let the mask extent all the way to
|
|
the second-level domain... */
|
|
wildsok = 1;
|
|
if (i == numseg || (i + 1) == numseg)
|
|
wildsok = 0;
|
|
if (wildsok == 0 && (index(ipseg[i], '*')
|
|
|| index(ipseg[i], '?')))
|
|
{
|
|
retval = FALSE;
|
|
}
|
|
/* MyFree(ipseg[i]); */
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return (retval);
|
|
#undef userhost
|
|
#undef IP_WILDS_OK
|
|
|
|
}
|
|
|
|
|
|
|
|
int m_svsnoop(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
aClient *acptr;
|
|
|
|
if (!(check_registered(sptr) && IsULine(sptr) && parc > 2))
|
|
return 0;
|
|
/* svsnoop bugfix --binary */
|
|
if (hunt_server(cptr, sptr, ":%s SVSNOOP %s :%s", 1, parc,
|
|
parv) == HUNTED_ISME)
|
|
{
|
|
if (parv[2][0] == '+')
|
|
{
|
|
SVSNOOP = 1;
|
|
sendto_ops("This server has been placed in NOOP mode");
|
|
for (acptr = &me; acptr; acptr = acptr->prev)
|
|
{
|
|
if (MyClient(acptr) && IsAnOper(acptr))
|
|
{
|
|
if (IsAnOper(acptr))
|
|
IRCstats.operators--;
|
|
acptr->umodes &=
|
|
~(UMODE_OPER | UMODE_LOCOP | UMODE_HELPOP | UMODE_SERVICES |
|
|
UMODE_SADMIN | UMODE_ADMIN);
|
|
acptr->umodes &=
|
|
~(UMODE_NETADMIN | UMODE_TECHADMIN | UMODE_CLIENT |
|
|
UMODE_FLOOD | UMODE_EYES | UMODE_WHOIS);
|
|
acptr->umodes &=
|
|
~(UMODE_KIX | UMODE_FCLIENT | UMODE_HIDING |
|
|
UMODE_DEAF | UMODE_HIDEOPER);
|
|
acptr->oflag = 0;
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
SVSNOOP = 0;
|
|
sendto_ops("This server is no longer in NOOP mode");
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
** m_svso - Stskeeps
|
|
** parv[0] = sender prefix
|
|
** parv[1] = nick
|
|
** parv[2] = options
|
|
*/
|
|
|
|
int m_svso(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
aClient *acptr;
|
|
long fLag;
|
|
|
|
if (!IsULine(sptr))
|
|
return 0;
|
|
|
|
if (parc < 3)
|
|
return 0;
|
|
|
|
if (!(acptr = find_client(parv[1], (aClient *)NULL)))
|
|
return 0;
|
|
|
|
if (!MyClient(acptr))
|
|
{
|
|
sendto_one(acptr, ":%s SVSO %s %s", parv[0], parv[1], parv[2]);
|
|
return 0;
|
|
}
|
|
|
|
if (*parv[2] == '+')
|
|
{
|
|
int *i, flag;
|
|
char *m = NULL;
|
|
for (m = (parv[2] + 1); *m; m++)
|
|
{
|
|
for (i = oper_access; flag = *i; i += 2)
|
|
{
|
|
if (*m == (char) *(i + 1))
|
|
{
|
|
acptr->oflag |= flag;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (*parv[2] == '-')
|
|
{
|
|
fLag = acptr->umodes;
|
|
if (IsAnOper(acptr))
|
|
IRCstats.operators--;
|
|
acptr->umodes &=
|
|
~(UMODE_OPER | UMODE_LOCOP | UMODE_HELPOP | UMODE_SERVICES |
|
|
UMODE_SADMIN | UMODE_ADMIN);
|
|
acptr->umodes &=
|
|
~(UMODE_NETADMIN | UMODE_TECHADMIN | UMODE_CLIENT |
|
|
UMODE_FLOOD | UMODE_EYES | UMODE_WHOIS);
|
|
acptr->umodes &=
|
|
~(UMODE_KIX | UMODE_FCLIENT | UMODE_HIDING |
|
|
UMODE_DEAF | UMODE_HIDEOPER);
|
|
acptr->oflag = 0;
|
|
send_umode_out(acptr, acptr, fLag);
|
|
}
|
|
}
|
|
|
|
|
|
/* ** m_akill;
|
|
** parv[0] = sender prefix
|
|
** parv[1] = hostmask
|
|
** parv[2] = username
|
|
** parv[3] = comment
|
|
*/
|
|
int m_akill(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
char *hostmask, *usermask, *comment;
|
|
ConfigItem_ban *bconf;
|
|
|
|
if (parc < 2 && IsPerson(sptr))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
|
|
me.name, parv[0], "AKILL");
|
|
return 0;
|
|
}
|
|
|
|
if (IsServer(sptr) && parc < 3)
|
|
return 0;
|
|
|
|
if (!IsServer(cptr))
|
|
{
|
|
if (!IsOper(sptr))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
|
|
sptr->name);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
comment = parc < 3 ? NULL : parv[2];
|
|
if ((hostmask = (char *)index(parv[1], '@')))
|
|
{
|
|
*hostmask = 0;
|
|
hostmask++;
|
|
usermask = parv[1];
|
|
}
|
|
else
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :%s", me.name,
|
|
sptr->name,
|
|
"Please use a nick!user@host mask.");
|
|
return 0;
|
|
}
|
|
if (!strchr(hostmask, '.'))
|
|
{
|
|
sendto_one(sptr,
|
|
"NOTICE %s :*** What a sweeping AKILL. If only your admin knew you tried that..",
|
|
parv[0]);
|
|
sendto_realops("%s attempted to /akill *@*",
|
|
parv[0]);
|
|
return 0;
|
|
}
|
|
if (MyClient(sptr))
|
|
{
|
|
sendto_realops("%s added akill for %s@%s (%s)",
|
|
sptr->name, usermask, hostmask,
|
|
!BadPtr(comment) ? comment : "no reason");
|
|
sendto_serv_butone(&me,
|
|
":%s GLOBOPS :%s added akill for %s@%s (%s)",
|
|
me.name, sptr->name, usermask, hostmask,
|
|
!BadPtr(comment) ? comment : "no reason");
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hostmask = parv[1];
|
|
usermask = parv[2];
|
|
comment = parc < 4 ? NULL : parv[3];
|
|
}
|
|
|
|
if (!usermask || !hostmask)
|
|
{
|
|
/*
|
|
* This is very bad, it should never happen.
|
|
*/
|
|
sendto_ops("Error adding akill from %s!", sptr->name);
|
|
return 0;
|
|
}
|
|
|
|
if (!(bconf = Find_banEx(make_user_host(usermask, hostmask), CONF_BAN_USER, CONF_BAN_TYPE_AKILL)))
|
|
{
|
|
bconf = (ConfigItem_ban *) MyMallocEx(sizeof(ConfigItem_ban));
|
|
bconf->flag.type = CONF_BAN_USER;
|
|
bconf->mask = strdup(make_user_host(usermask, hostmask));
|
|
bconf->reason = comment ? strdup(comment) : NULL;
|
|
bconf->flag.type2 = CONF_BAN_TYPE_AKILL;
|
|
add_ConfigItem((ConfigItem *) bconf, (ConfigItem **) &conf_ban);
|
|
}
|
|
|
|
if (comment)
|
|
sendto_serv_butone(cptr, ":%s AKILL %s %s :%s",
|
|
IsServer(cptr) ? parv[0] : me.name, hostmask,
|
|
usermask, comment);
|
|
else
|
|
sendto_serv_butone(cptr, ":%s AKILL %s %s",
|
|
IsServer(cptr) ? parv[0] : me.name, hostmask, usermask);
|
|
|
|
|
|
check_pings(TStime(), 1);
|
|
|
|
}
|
|
|
|
/*
|
|
** m_rakill;
|
|
** parv[0] = sender prefix
|
|
** parv[1] = hostmask
|
|
** parv[2] = username
|
|
** parv[3] = comment
|
|
*/
|
|
int m_rakill(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
char *hostmask, *usermask;
|
|
ConfigItem_ban *bconf;
|
|
int result;
|
|
|
|
if (parc < 2 && IsPerson(sptr))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
|
|
me.name, parv[0], "RAKILL");
|
|
return 0;
|
|
}
|
|
|
|
if (IsServer(sptr) && parc < 3)
|
|
return 0;
|
|
|
|
if (!IsServer(cptr))
|
|
{
|
|
if (!IsOper(sptr))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name,
|
|
sptr->name);
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
if ((hostmask = (char *)index(parv[1], '@')))
|
|
{
|
|
*hostmask = 0;
|
|
hostmask++;
|
|
usermask = parv[1];
|
|
}
|
|
else
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :*** %s", me.name,
|
|
sptr->name, "Please use a user@host mask.");
|
|
return 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hostmask = parv[1];
|
|
usermask = parv[2];
|
|
}
|
|
|
|
if (!usermask || !hostmask)
|
|
{
|
|
/*
|
|
* This is very bad, it should never happen.
|
|
*/
|
|
sendto_realops("Error adding akill from %s!", sptr->name);
|
|
return 0;
|
|
}
|
|
|
|
if (!(bconf = Find_banEx(make_user_host(usermask, hostmask), CONF_BAN_USER, CONF_BAN_TYPE_AKILL)))
|
|
{
|
|
if (!MyClient(sptr))
|
|
{
|
|
sendto_serv_butone(cptr, ":%s RAKILL %s %s",
|
|
IsServer(cptr) ? parv[0] : me.name, hostmask,
|
|
usermask);
|
|
return 0;
|
|
}
|
|
sendto_one(sptr, ":%s NOTICE %s :*** AKill %s@%s does not exist.",
|
|
me.name, sptr->name, usermask, hostmask);
|
|
return 0;
|
|
|
|
}
|
|
if (bconf->flag.type != CONF_BAN_TYPE_AKILL)
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :*** Error: Cannot remove other ban types",
|
|
me.name, sptr->name);
|
|
return 0;
|
|
}
|
|
if (MyClient(sptr))
|
|
{
|
|
sendto_ops("%s removed akill for %s@%s",
|
|
sptr->name, usermask, hostmask);
|
|
sendto_serv_butone(&me,
|
|
":%s GLOBOPS :%s removed akill for %s@%s",
|
|
me.name, sptr->name, usermask, hostmask);
|
|
}
|
|
|
|
/* Wipe it out. */
|
|
del_ConfigItem(bconf, &conf_me);
|
|
MyFree(bconf->mask);
|
|
if (bconf->reason)
|
|
MyFree(bconf->reason);
|
|
MyFree(bconf);
|
|
|
|
sendto_serv_butone(cptr, ":%s RAKILL %s %s",
|
|
IsServer(cptr) ? parv[0] : me.name, hostmask, usermask);
|
|
|
|
check_pings(TStime(), 1);
|
|
}
|
|
|
|
|
|
/*
|
|
* m_zline add a temporary zap line
|
|
* parv[0] = sender prefix
|
|
* parv[1] = host
|
|
* parv[2] = reason
|
|
*/
|
|
|
|
int m_zline(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
char userhost[512 + 2] = "", *in;
|
|
int uline = 0, i = 0, propo = 0;
|
|
char *reason, *mask, *server, *person;
|
|
aClient *acptr;
|
|
ConfigItem_ban *bconf;
|
|
|
|
reason = mask = server = person = NULL;
|
|
|
|
reason = ((parc >= 3) ? parv[parc - 1] : "Reason unspecified");
|
|
mask = ((parc >= 2) ? parv[parc - 2] : NULL);
|
|
server = ((parc >= 4) ? parv[parc - 1] : NULL);
|
|
|
|
if (parc == 4)
|
|
{
|
|
mask = parv[parc - 3];
|
|
server = parv[parc - 2];
|
|
reason = parv[parc - 1];
|
|
}
|
|
|
|
uline = IsULine(sptr) ? 1 : 0;
|
|
|
|
if (!uline && (!MyConnect(sptr) || !OPCanZline(sptr) || !IsOper(sptr)))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
|
|
return -1;
|
|
}
|
|
|
|
if (uline)
|
|
{
|
|
if (parc >= 4 && server)
|
|
{
|
|
if (hunt_server(cptr, sptr, ":%s ZLINE %s %s :%s", 2,
|
|
parc, parv) != HUNTED_ISME)
|
|
return 0;
|
|
else;
|
|
}
|
|
else
|
|
propo = 1;
|
|
}
|
|
|
|
if (parc < 2)
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
|
|
me.name, parv[0], "ZLINE");
|
|
return -1;
|
|
}
|
|
|
|
if (acptr = find_client(parv[1], NULL))
|
|
{
|
|
strcpy(userhost, inetntoa((char *)&acptr->ip));
|
|
person = &acptr->name[0];
|
|
acptr = NULL;
|
|
}
|
|
/* z-lines don't support user@host format, they only
|
|
work with ip addresses and nicks */
|
|
else if ((in = index(parv[1], '@')) && (*(in + 1) != '\0'))
|
|
{
|
|
strcpy(userhost, in + 1);
|
|
in = &userhost[0];
|
|
while (*in)
|
|
{
|
|
if (!isdigit(*in) && !ispunct(*in))
|
|
{
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** z:lines work only with ip addresses (you cannot specify ident either)",
|
|
me.name, sptr->name);
|
|
return;
|
|
}
|
|
in++;
|
|
}
|
|
}
|
|
else if (in && !(*(in + 1))) /* sheesh not only specifying a ident@, but
|
|
omitting the ip...? */
|
|
{
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** Hey! z:lines need an ip address...",
|
|
me.name, sptr->name);
|
|
return -1;
|
|
}
|
|
else
|
|
{
|
|
strcpy(userhost, parv[1]);
|
|
in = &userhost[0];
|
|
while (*in)
|
|
{
|
|
if (!isdigit(*in) && !ispunct(*in))
|
|
{
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** z:lines work only with ip addresses (you cannot specify ident either)",
|
|
me.name, sptr->name);
|
|
return;
|
|
}
|
|
in++;
|
|
}
|
|
}
|
|
|
|
/* this'll protect against z-lining *.* or something */
|
|
if (advanced_check(userhost, TRUE) == FALSE)
|
|
{
|
|
sendto_ops("Bad z:line mask from %s *@%s [%s]", parv[0],
|
|
userhost, reason ? reason : "");
|
|
if (MyClient(sptr))
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :** *@%s is a bad z:line mask...",
|
|
me.name, sptr->name, userhost);
|
|
return;
|
|
}
|
|
|
|
if (!(bconf = Find_ban(userhost, CONF_BAN_IP)))
|
|
{
|
|
if (uline == 0)
|
|
{
|
|
if (person)
|
|
sendto_realops("%s added a temp z:line for %s (*@%s) [%s]",
|
|
parv[0], person, userhost, reason ? reason : "");
|
|
else
|
|
sendto_realops("%s added a temp z:line *@%s [%s]", parv[0],
|
|
userhost, reason ? reason : "");
|
|
}
|
|
else
|
|
{
|
|
if (person)
|
|
sendto_ops("%s z:lined %s (*@%s) on %s [%s]", parv[0],
|
|
person, userhost, server ? server : ircnetwork,
|
|
reason ? reason : "");
|
|
else
|
|
sendto_ops("%s z:lined *@%s on %s [%s]", parv[0],
|
|
userhost, server ? server : ircnetwork,
|
|
reason ? reason : "");
|
|
|
|
}
|
|
bconf = (ConfigItem_ban *) MyMallocEx(sizeof(ConfigItem_ban));
|
|
bconf->flag.type = CONF_BAN_IP;
|
|
bconf->mask = strdup(userhost);
|
|
bconf->reason = strdup(reason);
|
|
bconf->flag.type2 = uline ? CONF_BAN_TYPE_AKILL : CONF_BAN_TYPE_TEMPORARY;
|
|
}
|
|
else
|
|
{
|
|
goto propo_label;
|
|
}
|
|
if (!match(mask, inetntoa((char *)&cptr->ip)))
|
|
{
|
|
sendto_realops("Tried to zap cptr, from %s",
|
|
parv[0]);
|
|
MyFree(bconf);
|
|
}
|
|
else
|
|
{
|
|
add_ConfigItem((ConfigItem *)bconf, (ConfigItem **)&conf_ban);
|
|
}
|
|
propo_label:
|
|
if (propo == 1) /* propo is if a ulined server is propagating a z-line
|
|
this should go after the above check */
|
|
sendto_serv_butone(cptr, ":%s ZLINE %s :%s", parv[0], parv[1],
|
|
reason ? reason : "");
|
|
|
|
check_pings(TStime(), 1);
|
|
}
|
|
|
|
/*
|
|
* m_unzline remove a temporary zap line
|
|
* parv[0] = sender prefix
|
|
* parv[1] = host
|
|
*/
|
|
|
|
int m_unzline(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
char userhost[512 + 2] = "", *in;
|
|
int result = 0, uline = 0, akill = 0;
|
|
char *mask, *server;
|
|
ConfigItem_ban *bconf;
|
|
uline = IsULine(sptr) ? 1 : 0;
|
|
|
|
if (parc < 2)
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
|
|
me.name, parv[0], "UNZLINE");
|
|
return -1;
|
|
}
|
|
|
|
|
|
if (parc < 3 || !uline)
|
|
{
|
|
mask = parv[parc - 1];
|
|
server = NULL;
|
|
}
|
|
else if (parc == 3)
|
|
{
|
|
mask = parv[parc - 2];
|
|
server = parv[parc - 1];
|
|
}
|
|
|
|
if (!uline && (!MyConnect(sptr) || !OPCanZline(sptr) || !IsOper(sptr)))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
|
|
return -1;
|
|
}
|
|
|
|
/* before we even check ourselves we need to do the uline checks
|
|
because we aren't supposed to add a z:line if the message is
|
|
destined to be passed on... */
|
|
|
|
if (uline)
|
|
{
|
|
if (parc == 3 && server)
|
|
{
|
|
if (hunt_server(cptr, sptr, ":%s UNZLINE %s %s", 2,
|
|
parc, parv) != HUNTED_ISME)
|
|
return 0;
|
|
else;
|
|
}
|
|
else
|
|
sendto_serv_butone(cptr, ":%s UNZLINE %s", parv[0],
|
|
parv[1]);
|
|
|
|
}
|
|
|
|
|
|
/* parse the removal mask the same way so an oper can just use
|
|
the same thing to remove it if they specified *@ or something... */
|
|
if ((in = index(parv[1], '@')))
|
|
{
|
|
strcpy(userhost, in + 1);
|
|
in = &userhost[0];
|
|
while (*in)
|
|
{
|
|
if (!isdigit(*in) && !ispunct(*in))
|
|
{
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** it's not possible to have a z:line that's not an ip addresss...",
|
|
me.name, sptr->name);
|
|
return;
|
|
}
|
|
in++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strcpy(userhost, parv[1]);
|
|
in = &userhost[0];
|
|
while (*in)
|
|
{
|
|
if (!isdigit(*in) && !ispunct(*in))
|
|
{
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** it's not possible to have a z:line that's not an ip addresss...",
|
|
me.name, sptr->name);
|
|
return;
|
|
}
|
|
in++;
|
|
}
|
|
}
|
|
|
|
akill = 0;
|
|
retry_unzline:
|
|
|
|
bconf = Find_ban(userhost, CONF_BAN_IP);
|
|
if (!bconf)
|
|
{
|
|
if (MyClient(sptr))
|
|
sendto_one(sptr, ":%s NOTICE %s :*** Cannot find z:line %s",
|
|
me.name, sptr->name, userhost);
|
|
return 0;
|
|
}
|
|
|
|
if (uline == 0)
|
|
{
|
|
if (bconf->flag.type2 != CONF_BAN_TYPE_TEMPORARY)
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :*** You may not remove permanent z:lines.",
|
|
me.name, sptr->name);
|
|
return 0;
|
|
}
|
|
}
|
|
del_ConfigItem((ConfigItem *)bconf, (ConfigItem **)&conf_ban);
|
|
sendto_realops("%s removed z:line %s", parv[0], userhost);
|
|
if (bconf->mask)
|
|
MyFree(bconf->mask);
|
|
if (bconf->reason)
|
|
MyFree(bconf->reason);
|
|
MyFree(bconf);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
** m_kline;
|
|
** parv[0] = sender prefix
|
|
** parv[1] = nickname
|
|
** parv[2] = comment or filename
|
|
*/
|
|
int m_kline(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
char *host, *tmp, *hosttemp;
|
|
char uhost[80], name[80];
|
|
int ip1, ip2, ip3, temp;
|
|
aClient *acptr;
|
|
ConfigItem_ban *bconf;
|
|
|
|
if (!MyClient(sptr) || !OPCanKline(sptr))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
|
|
return 0;
|
|
}
|
|
|
|
|
|
if (parc < 2)
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NEEDMOREPARAMS),
|
|
me.name, parv[0], "KLINE");
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* This patch allows opers to quote kline by address as well as nick
|
|
* --Russell
|
|
*/
|
|
if (hosttemp = (char *)strchr((char *)parv[1], '@'))
|
|
{
|
|
temp = 0;
|
|
while (temp <= 20)
|
|
name[temp++] = 0;
|
|
strcpy(uhost, ++hosttemp);
|
|
strncpy(name, parv[1], hosttemp - 1 - parv[1]);
|
|
if (name[0] == '\0' || uhost[0] == '\0')
|
|
{
|
|
Debug((DEBUG_INFO, "KLINE: Bad field!"));
|
|
sendto_one(sptr,
|
|
"NOTICE %s :*** If you're going to add a userhost, at LEAST specify both fields",
|
|
parv[0]);
|
|
return 0;
|
|
}
|
|
if (!strcmp(uhost, "*") || !strchr(uhost, '.'))
|
|
{
|
|
sendto_one(sptr,
|
|
"NOTICE %s :*** What a sweeping K:Line. If only your admin knew you tried that..",
|
|
parv[0]);
|
|
sendto_realops("%s attempted to /kline *@*", parv[0]);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/* by nick */
|
|
else
|
|
{
|
|
if (!(acptr = find_client(parv[1], NULL)))
|
|
{
|
|
if (!(acptr =
|
|
get_history(parv[1], (long)KILLCHASETIMELIMIT)))
|
|
{
|
|
sendto_one(sptr,
|
|
"NOTICE %s :*** Can't find user %s to add KLINE",
|
|
parv[0], parv[1]);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (!acptr->user)
|
|
return 0;
|
|
|
|
strcpy(name, acptr->user->username);
|
|
if (MyClient(acptr))
|
|
host = acptr->sockhost;
|
|
else
|
|
host = acptr->user->realhost;
|
|
|
|
/* Sanity checks */
|
|
|
|
if (name == '\0' || host == '\0')
|
|
{
|
|
Debug((DEBUG_INFO, "KLINE: Bad field"));
|
|
sendto_one(sptr, "NOTICE %s :*** Bad field!", parv[0]);
|
|
return 0;
|
|
}
|
|
|
|
/* Add some wildcards */
|
|
|
|
|
|
strcpy(uhost, host);
|
|
if (isdigit(host[strlen(host) - 1]))
|
|
{
|
|
if (sscanf(host, "%d.%d.%d.%*d", &ip1, &ip2, &ip3))
|
|
ircsprintf(uhost, "%d.%d.%d.*", ip1, ip2, ip3);
|
|
}
|
|
else if (sscanf(host, "%*[^.].%*[^.].%s", uhost))
|
|
{ /* Not really... */
|
|
tmp = (char *)strchr(host, '.');
|
|
ircsprintf(uhost, "*%s", tmp);
|
|
}
|
|
}
|
|
|
|
sendto_realops("%s added a temporary user ban for %s@%s %s", parv[0], name, uhost,
|
|
parv[2] ? parv[2] : "");
|
|
ircd_log("%s added a temporary user ban for %s@%s %s",
|
|
parv[0], name, uhost,
|
|
parv[2] ? parv[2] : "");
|
|
bconf = (ConfigItem_ban *)MyMallocEx(sizeof(ConfigItem_ban));
|
|
bconf->flag.type = CONF_BAN_USER;
|
|
bconf->mask = strdup(make_user_host(name, uhost));
|
|
bconf->reason = parv[2] ? strdup(parv[2]) : NULL;
|
|
bconf->flag.type2 = CONF_BAN_TYPE_TEMPORARY;
|
|
add_ConfigItem((ConfigItem *) bconf, (ConfigItem **) &conf_ban);
|
|
check_pings(TStime(), 1);
|
|
}
|
|
|
|
/*
|
|
* m_unkline
|
|
* parv[0] = sender prefix
|
|
* parv[1] = userhost
|
|
*/
|
|
|
|
int m_unkline(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
|
|
int result, temp;
|
|
char *hosttemp = parv[1], host[80], name[80];
|
|
ConfigItem_ban *bconf;
|
|
|
|
|
|
if (!MyClient(sptr) || !OPCanUnKline(sptr))
|
|
{
|
|
sendto_one(sptr, err_str(ERR_NOPRIVILEGES), me.name, parv[0]);
|
|
return 0;
|
|
}
|
|
if (parc < 2)
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :*** Not enough parameters", me.name, parv[0]);
|
|
return 0;
|
|
}
|
|
if (hosttemp = (char *)strchr((char *)parv[1], '@'))
|
|
{
|
|
temp = 0;
|
|
while (temp <= 20)
|
|
name[temp++] = 0;
|
|
strcpy(host, ++hosttemp);
|
|
strncpy(name, parv[1], hosttemp - 1 - parv[1]);
|
|
if (name[0] == '\0' || host[0] == '\0')
|
|
{
|
|
Debug((DEBUG_INFO, "UNKLINE: Bad field"));
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** Both user and host fields must be non-null",
|
|
me.name, parv[0]);
|
|
return 0;
|
|
}
|
|
if (!(bconf = Find_banEx(make_user_host(name, host), CONF_BAN_USER, CONF_BAN_TYPE_TEMPORARY)))
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :*** Cannot find user ban %s@%s",
|
|
me.name, parv[0], name, host);
|
|
return 0;
|
|
}
|
|
if (bconf->flag.type2 != CONF_BAN_TYPE_TEMPORARY)
|
|
{
|
|
sendto_one(sptr, ":%s NOTICE %s :*** You cannot remove permament user bans",
|
|
me.name, sptr->name);
|
|
return 0;
|
|
}
|
|
|
|
del_ConfigItem((ConfigItem *)bconf, (ConfigItem **)&conf_ban);
|
|
if (bconf->mask)
|
|
MyFree(bconf->mask);
|
|
if (bconf->reason)
|
|
MyFree(bconf->reason);
|
|
MyFree(bconf);
|
|
|
|
sendto_one(sptr,
|
|
":%s NOTICE %s :*** Temporary user ban %s@%s is now removed.",
|
|
me.name, parv[0], name, host);
|
|
sendto_realops("%s removed temporary user ban %s@%s", parv[0],
|
|
name, host);
|
|
ircd_log(
|
|
"%s removed temporary user ban %s@%s",
|
|
parv[0], name, host);
|
|
return 0;
|
|
}
|
|
/* This wasn't here before -- Barubary */
|
|
check_pings(TStime(), 1);
|
|
}
|
|
|
|
|
|
/* m_sqline
|
|
** parv[0] = sender
|
|
** parv[1] = nickmask
|
|
** parv[2] = reason
|
|
*/
|
|
int m_sqline(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
ConfigItem_ban *bconf;
|
|
/* So we do not make double entries */
|
|
int addit = 0;
|
|
if (!IsServer(sptr) || parc < 2)
|
|
return 0;
|
|
|
|
if (parv[2])
|
|
sendto_serv_butone_token(cptr, parv[0], MSG_SQLINE, TOK_SQLINE,
|
|
"%s :%s", parv[1], parv[2]);
|
|
else
|
|
sendto_serv_butone_token(cptr, parv[0], MSG_SQLINE, TOK_SQLINE,
|
|
"%s", parv[1]);
|
|
|
|
/* Only replaces AKILL (global ban nick)'s */
|
|
if (bconf = Find_banEx(parv[1], CONF_BAN_NICK, CONF_BAN_TYPE_AKILL))
|
|
{
|
|
if (bconf->mask)
|
|
MyFree(bconf->mask);
|
|
if (bconf->reason)
|
|
MyFree(bconf->reason);
|
|
bconf->mask = NULL;
|
|
bconf->reason = NULL;
|
|
addit = 1;
|
|
}
|
|
else
|
|
bconf = (ConfigItem_ban *) MyMallocEx(sizeof(ConfigItem_ban));
|
|
if (parv[2])
|
|
DupString(bconf->reason, parv[2]);
|
|
if (parv[1])
|
|
DupString(bconf->mask, parv[1]);
|
|
|
|
/* CONF_BAN_NICK && CONF_BAN_TYPE_AKILL == SQLINE */
|
|
bconf->flag.type2 = CONF_BAN_TYPE_AKILL;
|
|
if (addit == 1)
|
|
add_ConfigItem((ConfigItem *) bconf, (ConfigItem **) &conf_ban);
|
|
|
|
}
|
|
/* m_unsqline
|
|
** parv[0] = sender
|
|
** parv[1] = nickmask
|
|
*/
|
|
int m_unsqline(cptr, sptr, parc, parv)
|
|
aClient *cptr, *sptr;
|
|
int parc;
|
|
char *parv[];
|
|
{
|
|
ConfigItem_ban *bconf;
|
|
|
|
if (!IsServer(sptr) || parc < 2)
|
|
return 0;
|
|
|
|
sendto_serv_butone_token(cptr, parv[0], MSG_UNSQLINE, TOK_UNSQLINE,
|
|
"%s", parv[1]);
|
|
|
|
if (bconf = Find_banEx(parv[1], CONF_BAN_NICK, CONF_BAN_TYPE_AKILL))
|
|
{
|
|
del_ConfigItem(bconf, &conf_me);
|
|
if (bconf->mask)
|
|
MyFree(bconf->mask);
|
|
if (bconf->reason)
|
|
MyFree(bconf->reason);
|
|
MyFree(bconf);
|
|
}
|
|
else
|
|
return;
|
|
|
|
return 0;
|
|
}
|