Beispiel #1
0
/* add a tandem bot to our chain list */
void addbot(char *who, char *from, char *next, char flag, int vernum)
{
  tand_t **ptr = &tandbot, *ptr2;

  Context;
  while (*ptr) {
    if (!strcasecmp((*ptr)->bot, who))
      putlog(LOG_BOTS, "*", "!!! Duplicate botnet bot entry!!");
    ptr = &((*ptr)->next);
  }
  ptr2 = nmalloc(sizeof(tand_t));
  strncpy(ptr2->bot, who, HANDLEN);
  ptr2->bot[HANDLEN] = 0;
  ptr2->share = flag;
  ptr2->ver = vernum;
  ptr2->next = *ptr;
  *ptr = ptr2;
  /* may be via itself */
  ptr2->via = findbot(from);
  if (!strcasecmp(next, botnetnick))
    ptr2->uplink = (tand_t *) 1;
  else
    ptr2->uplink = findbot(next);
  tands++;
}
Beispiel #2
0
static void bot_unlinked(int idx, char *par)
{
  int i;
  char *bot = NULL;

  bot = newsplit(&par);
  i = nextbot(bot);
  if ((i >= 0) && (i != idx))	/* Bot is NOT downstream along idx, so
				 * BOGUS! */
    fake_alert(idx, "direction", bot, "unlinked");
  else if (i >= 0) {		/* Valid bot downstream of idx */
    if (par[0])
/* #ifdef HUB */
      chatout("*** (%s) %s\n", lastbot(bot), par);
/*
#else
      chatout("*** %s unlinked from botnet.\n", par);
#endif 
*/
    botnet_send_unlinked(idx, bot, par);
    unvia(idx, findbot(bot));
    rembot(bot);
  }
  /* Otherwise it's not even a valid bot, so just ignore! */
}
Beispiel #3
0
static void bot_linked(int idx, char *par)
{
  char s[1024];
  int bots, users;

  bots = bots_in_subtree(findbot(dcc[idx].nick));
  users = users_in_subtree(findbot(dcc[idx].nick));
  putlog(LOG_BOTS, "*", "%s", BOT_OLDBOT);
  simple_sprintf(s, "%s %s (%s) (lost %d bot%s and %d user%s",
                 MISC_DISCONNECTED, dcc[idx].nick, MISC_OUTDATED,
                 bots, (bots != 1) ? "s" : "", users, (users != 1) ? "s" : "");
  chatout("*** %s\n", s);
  botnet_send_unlinked(idx, dcc[idx].nick, s);
  killsock(dcc[idx].sock);
  lostdcc(idx);
}
Beispiel #4
0
	/*
	 ** NICK - new
	 **	  source  = NULL
	 **	  parv[0] = nickname
	 **	  parv[1] = hopcount
	 **	  parv[2] = timestamp
	 **	  parv[3] = modes
	 **	  parv[4] = username
	 **	  parv[5] = hostname
	 **	  parv[6] = server
	 **	  parv[7] = servicestamp
	 **	  parv[8] = IP
	 **	  parv[9] = info
	 ** NICK - change
	 **	  source  = oldnick
	 **	  parv[0] = new nickname
	 **	  parv[1] = hopcount
	 */
	bool OnNick(const Anope::string &source, const std::vector<Anope::string> &params)
	{
		if (params.size() != 2)
		{
			/* Currently bahamut has no ipv6 support */
			sockaddrs ip;
			ip.ntop(AF_INET, params[8].c_str());

			User *user = do_nick(source, params[0], params[4], params[5], params[6], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, ip.addr(), "", "", params[3]);
			if (user && nickserv)
			{
				NickAlias *na;
				if (user->timestamp == convertTo<time_t>(params[7]) && (na = findnick(user->nick)))
				{
					user->Login(na->nc);
					if (!Config->NoNicknameOwnership && na->nc->HasFlag(NI_UNCONFIRMED) == false)
						user->SetMode(findbot(Config->NickServ), UMODE_REGISTERED);
				}
				else
					nickserv->Validate(user);
			}
		}
		else
			do_nick(source, params[0], "", "", "", "", Anope::string(params[1]).is_pos_number_only() ? convertTo<time_t>(params[1]) : 0, "", "", "", "");

		return true;
	}
Beispiel #5
0
int in_chain(char *who)
{
  if (findbot(who))
    return 1;
  if (!strcasecmp(who, botnetnick))
    return 1;
  return 0;
}
Beispiel #6
0
static void bot_bye(int idx, char *par)
{
  char s[1024];
  int users, bots;

  bots = bots_in_subtree(findbot(dcc[idx].nick));
  users = users_in_subtree(findbot(dcc[idx].nick));
  simple_sprintf(s, "%s %s. %s (lost %d bot%s and %d user%s)",
                 BOT_DISCONNECTED, dcc[idx].nick, par[0] ?
                 par : "No reason", bots, (bots != 1) ?
                 "s" : "", users, (users != 1) ? "s" : "");
  putlog(LOG_BOTS, "*", "%s", s);
  chatout("*** %s\n", s);
  botnet_send_unlinked(idx, dcc[idx].nick, s);
  dprintf(idx, "*bye\n");
  killsock(dcc[idx].sock);
  lostdcc(idx);
}
Beispiel #7
0
static void bot_bye(int idx, char *par)
{
  char s[1024] = "";
  int users, bots;

  bots = bots_in_subtree(findbot(dcc[idx].nick));
  users = users_in_subtree(findbot(dcc[idx].nick));
  simple_snprintf(s, sizeof(s), "%s %s. %s (lost %d bot%s and %d user%s)",
		 "Disconnected from:",
                 (conf.bot->hub || (conf.bot->localhub && bot_aggressive_to(dcc[idx].user))) ? dcc[idx].nick : "botnet",
                  par[0] ? par : "No reason", bots, (bots != 1) ?
		 "s" : "", users, (users != 1) ? "s" : "");
  putlog(LOG_BOTS, "*", "%s", s);
  chatout("*** %s\n", s);
  botnet_send_unlinked(idx, dcc[idx].nick, s);
  dprintf(idx, "*bye\n");
  killsock(dcc[idx].sock);
  lostdcc(idx);
}
Beispiel #8
0
/**
 * add a bot to a channel
 */
void add_bot_to_chan(char *botname, char *chan) {
	bot *b = findbot(botname);
	botchan *bc = scalloc(sizeof(botchan),1);
	bc->next = b->chanlist;
	if (b->chanlist) {
		b->chanlist->prev = bc;
	}
	b->chanlist = bc;
	bc->chan = sstrdup(chan);
}
Beispiel #9
0
/**
 * remove a bot from a channel
 */
void remove_bot_from_chan(char *botname, char *chan) {
	bot *b = findbot(botname);
	botchan *bc = b->chanlist;
	while (bc) {
		if (stricmp(bc->chan,chan)==0) {
			chan_del_bot(b,bc);
		}
		bc = bc->next;
	}
}
Beispiel #10
0
	ChanServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE), expires(this)
	{
		this->SetAuthor("Anope");

		BotInfo *ChanServ = findbot(Config->ChanServ);
		if (ChanServ == NULL)
			throw ModuleException("No bot named " + Config->ChanServ);

		Implementation i[] = { I_OnBotPrivmsg, I_OnDelCore, I_OnPreHelp, I_OnPostHelp };
		ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
	}
Beispiel #11
0
/* once a minute, send 'ping' to each bot -- no exceptions */
void check_botnet_pings()
{
  int i;

  Context;
  for (i = 0; i < dcc_total; i++)
    if (dcc[i].type == &DCC_BOT)
      if (dcc[i].status & STAT_PINGED) {
	char s[1024];

	putlog(LOG_BOTS, "*", "%s: %s", BOT_PINGTIMEOUT, dcc[i].nick);
	simple_sprintf(s, "%s: %s", BOT_PINGTIMEOUT, dcc[i].nick);
	chatout("*** %s\n", s);
	botnet_send_unlinked(i, dcc[i].nick, s);
	killsock(dcc[i].sock);
	lostdcc(i);
      }
  Context;
  for (i = 0; i < dcc_total; i++)
    if (dcc[i].type == &DCC_BOT) {
      botnet_send_ping(i);
      dcc[i].status |= STAT_PINGED;
    }
  Context;
  for (i = 0; i < dcc_total; i++)
    if ((dcc[i].type == &DCC_BOT) && (dcc[i].status & STAT_LEAF)) {
      tand_t *bot, *via = findbot(dcc[i].nick);

      for (bot = tandbot; bot; bot = bot->next) {
	if ((via == bot->via) && (bot != via)) {
	  /* not leaflike behavior */
	  if (dcc[i].status & STAT_WARNED) {
	    char s[1024];

	    putlog(LOG_BOTS, "*", "%s %s (%s).", BOT_DISCONNECTED,
		   dcc[i].nick, BOT_BOTNOTLEAFLIKE);
	    dprintf(i, "bye\n");
	    simple_sprintf(s, "%s %s (%s)", BOT_DISCONNECTED, dcc[i].nick,
			   BOT_BOTNOTLEAFLIKE);
	    chatout("*** %s\n", s);
	    botnet_send_unlinked(i, dcc[i].nick, s);
	    killsock(dcc[i].sock);
	    lostdcc(i);
	  } else {
	    botnet_send_reject(i, botnetnick, NULL, bot->bot,
			       NULL, NULL);
	    dcc[i].status |= STAT_WARNED;
	  }
	} else
	  dcc[i].status &= ~STAT_WARNED;
      }
    }
  Context;
}
Beispiel #12
0
/**
 * find a bot on a channel
 */
bot *findbot_onchan(char *botname,char *chan) {
	bot *b = findbot(botname);
	botchan *bc = b->chanlist;
	while (bc) {
		if (stricmp(bc->chan,chan)==0) {
			return b;
		}
		bc = bc->next;
	}
	return NULL;
}
Beispiel #13
0
/* return name of the bot that is directly connected to bot X */
char *lastbot(char *who)
{
  tand_t *bot = findbot(who);

  if (!bot)
    return "*";
  else if (bot->uplink == (tand_t *) 1)
    return botnetnick;
  else
    return bot->uplink->bot;
}
Beispiel #14
0
	MemoServCore(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, CORE),
		mymemoserv(this)
	{
		this->SetAuthor("Anope");

		MemoServ = findbot(Config->MemoServ);
		if (MemoServ == NULL)
			throw ModuleException("No bot named " + Config->MemoServ);

		Implementation i[] = { I_OnNickIdentify, I_OnJoinChannel, I_OnUserAway, I_OnNickUpdate, I_OnPreHelp, I_OnPostHelp };
		ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation));
	}
Beispiel #15
0
	EventReturn OnChannelModeSet(Channel *c, ChannelModeName Name, const Anope::string &param)
	{
		if (Name == CMODE_OP && c && c->ci && c->name.equals_ci(this->HelpChan))
		{
			User *u = finduser(param);

			if (u && c->ci->AccessFor(u).HasPriv("OPDEOPME"))
				u->SetMode(findbot(Config->OperServ), UMODE_HELPOP);
		}

		return EVENT_CONTINUE;
	}
Beispiel #16
0
void updatebot(int idx, char *who, char share, int vernum)
{
  tand_t *ptr = findbot(who);

  Context;
  if (ptr) {
    if (share)
      ptr->share = share;
    if (vernum)
      ptr->ver = vernum;
    botnet_send_update(idx, ptr);
  }
}
Beispiel #17
0
/**
 * remove a bot from the botlist
 */
void delete_bot(char *botname) {
	bot *b = findbot(botname);
	if (b->prev) {
		b->prev->next = b->next;
	} else {
		botlist = b->next;
	}

	if (b->next) {
		b->next->prev = b->prev;
	}
	free(b);
}
Beispiel #18
0
/* return index into dcc list of the bot that connects us to bot <x> */
int nextbot(char *who)
{
  int j;
  tand_t *bot = findbot(who);

  if (!bot)
    return -1;

  for (j = 0; j < dcc_total; j++)
    if (bot->via && !strcasecmp(bot->via->bot, dcc[j].nick) &&
	(dcc[j].type == &DCC_BOT))
      return j;
  return -1;			/* we're not connected to 'via' */
}
Beispiel #19
0
	void Tick(time_t)
	{
		if (!session_service)
			return;
		for (unsigned i = session_service->GetExceptions().size(); i > 0; --i)
		{
			Exception *e = session_service->GetExceptions()[i - 1];

			if (!e->expires || e->expires > Anope::CurTime)
				continue;
			BotInfo *bi = findbot(Config->OperServ);
			if (Config->WallExceptionExpire && bi)
				ircdproto->SendGlobops(bi, "Session exception for %s has expired.", e->mask.c_str());
			session_service->DelException(e);
			delete e;
		}
	}
Beispiel #20
0
	/* JOIN - SJOIN */
	void SendJoin(User *user, Channel *c, const ChannelStatus *status)
	{
		UplinkSocket::Message(user->nick) << "SJOIN " << c->creation_time << " " << c->name;
		if (status)
		{
			/* First save the channel status incase uc->Status == status */
			ChannelStatus cs = *status;
			/* If the user is internally on the channel with flags, kill them so that
			 * the stacker will allow this.
			 */
			UserContainer *uc = c->FindUser(user);
			if (uc != NULL)
				uc->Status->ClearFlags();

			BotInfo *setter = findbot(user->nick);
			for (unsigned i = 0; i < ModeManager::ChannelModes.size(); ++i)
				if (cs.HasFlag(ModeManager::ChannelModes[i]->Name))
					c->SetMode(setter, ModeManager::ChannelModes[i], user->nick, false);
		}
	}
Beispiel #21
0
	void DoCommand(XMLRPCServiceInterface *iface, XMLRPCClientSocket *source, XMLRPCRequest *request)
	{
		Anope::string service = request->data.size() > 0 ? request->data[0] : "";
		Anope::string user = request->data.size() > 1 ? request->data[1] : "";
		Anope::string command = request->data.size() > 2 ? request->data[2] : "";

		if (service.empty() || user.empty() || command.empty())
			request->reply("error", "Invalid parameters");
		else
		{
			BotInfo *bi = findbot(service);
			if (!bi)
				request->reply("error", "Invalid service");
			else
			{
				request->reply("result", "Success");

				dynamic_reference<User> u = finduser(user);
				bool created = false;
				if (!u)
				{
					u = new XMLRPCUser(user);
					created = true;
					request->reply("online", "no");
				}
				else
					request->reply("online", "yes");

				bi->OnMessage(u, command);

				if (created && u)
				{
					User *useru = u;
					XMLRPCUser *myu = debug_cast<XMLRPCUser *>(useru);
					if (!myu->GetOut().empty())
						request->reply("return", iface->Sanitize(myu->GetOut()));
					delete u;
				}
			}
		}
	}
Beispiel #22
0
/**
 * Is the given nick a network service
 * @param nick to check
 * @param int Check if botserv bots
 * @return int
 */
bool nickIsServices(const Anope::string &tempnick, bool bot)
{
	if (tempnick.empty())
		return false;

	Anope::string nick = tempnick;

	size_t at = nick.find('@');
	if (at != Anope::string::npos)
	{
		Anope::string servername = nick.substr(at + 1);
		if (!servername.equals_ci(Config->ServerName))
			return false;
		nick = nick.substr(0, at);
	}

	BotInfo *bi = findbot(nick);
	if (bi)
		return bot ? true : bi->HasFlag(BI_CORE);
	return false;
}
Beispiel #23
0
bool IRCdMessage::OnWhois(const Anope::string &source, const std::vector<Anope::string> &params)
{
	if (!source.empty() && !params.empty())
	{
		User *u = finduser(params[0]);
		if (u && u->server == Me)
		{
			BotInfo *bi = findbot(u->nick);
			ircdproto->SendNumeric(Config->ServerName, 311, source, "%s %s %s * :%s", u->nick.c_str(), u->GetIdent().c_str(), u->host.c_str(), u->realname.c_str());
			if (bi)
				ircdproto->SendNumeric(Config->ServerName, 307, source, "%s :is a registered nick", bi->nick.c_str());
			ircdproto->SendNumeric(Config->ServerName, 312, source, "%s %s :%s", u->nick.c_str(), Config->ServerName.c_str(), Config->ServerDesc.c_str());
			if (bi)
				ircdproto->SendNumeric(Config->ServerName, 317, source, "%s %ld %ld :seconds idle, signon time", bi->nick.c_str(), static_cast<long>(Anope::CurTime - bi->lastmsg), static_cast<long>(start_time));
			ircdproto->SendNumeric(Config->ServerName, 318, source, "%s :End of /WHOIS list.", params[0].c_str());
		}
		else
			ircdproto->SendNumeric(Config->ServerName, 401, source, "%s :No such user.", params[0].c_str());
	}

	return true;
}
Beispiel #24
0
static void bot_thisbot(int idx, char *par)
{
  if (strcasecmp(par, dcc[idx].nick)) {
    char s[1024] = "";

    putlog(LOG_BOTS, "*", "Wrong bot--wanted %s, got %s", dcc[idx].nick, par);
    dprintf(idx, "bye imposter\n");
    simple_snprintf(s, sizeof(s), "Disconnected %s (imposter)", dcc[idx].nick);
    chatout("*** %s\n", s);
    botnet_send_unlinked(idx, dcc[idx].nick, s);
    unvia(idx, findbot(dcc[idx].nick));
    killsock(dcc[idx].sock);
    lostdcc(idx);
    return;
  }

  /* Set capitalization the way they want it */
  noshare = 1;
  change_handle(dcc[idx].user, par);
  noshare = 0;
  strlcpy(dcc[idx].nick, par, sizeof(dcc[idx].nick));
}
Beispiel #25
0
/**
 * The /bs assign command.
 * @param u The user who issued the command
 * @param MOD_CONT to continue processing other modules, MOD_STOP to stop processing.
 **/
int do_assign(User * u)
{
    char *chan = strtok(NULL, " ");
    char *nick = strtok(NULL, " ");
    BotInfo *bi;
    ChannelInfo *ci;

    if (readonly)
        notice_lang(s_BotServ, u, BOT_ASSIGN_READONLY);
    else if (!chan || !nick)
        syntax_error(s_BotServ, u, "ASSIGN", BOT_ASSIGN_SYNTAX);
    else if (!(bi = findbot(nick)))
        notice_lang(s_BotServ, u, BOT_DOES_NOT_EXIST, nick);
    else if (bi->flags & BI_PRIVATE && !is_oper(u))
        notice_lang(s_BotServ, u, PERMISSION_DENIED);
    else if (!(ci = cs_findchan(chan)))
        notice_lang(s_BotServ, u, CHAN_X_NOT_REGISTERED, chan);
    else if (ci->flags & CI_VERBOTEN)
        notice_lang(s_BotServ, u, CHAN_X_FORBIDDEN, chan);
    else if ((ci->bi) && (stricmp(ci->bi->nick, nick) == 0))
        notice_lang(s_BotServ, u, BOT_ASSIGN_ALREADY, ci->bi->nick, chan);
    else if ((ci->botflags & BS_NOBOT)
             || (!check_access(u, ci, CA_ASSIGN) && !is_services_admin(u)))
        notice_lang(s_BotServ, u, PERMISSION_DENIED);
    else {
        if (ci->bi)
            unassign(u, ci);
        ci->bi = bi;
        bi->chancount++;
        if (ci->c && ci->c->usercount >= BSMinUsers) {
            bot_join(ci);
        }
        notice_lang(s_BotServ, u, BOT_ASSIGN_ASSIGNED, bi->nick, ci->name);
        send_event(EVENT_BOT_ASSIGN, 2, ci->name, bi->nick);
    }
    return MOD_CONT;
}
Beispiel #26
0
static void bot_thisbot(int idx, char *par)
{
  if (egg_strcasecmp(par, dcc[idx].nick)) {
    char s[1024];

    putlog(LOG_BOTS, "*", NET_WRONGBOT, dcc[idx].nick, par);
    dprintf(idx, "bye %s\n", MISC_IMPOSTER);
    simple_sprintf(s, "%s %s (%s)", MISC_DISCONNECTED, dcc[idx].nick,
                   MISC_IMPOSTER);
    chatout("*** %s\n", s);
    botnet_send_unlinked(idx, dcc[idx].nick, s);
    unvia(idx, findbot(dcc[idx].nick));
    killsock(dcc[idx].sock);
    lostdcc(idx);
    return;
  }
  if (bot_flags(dcc[idx].user) & BOT_LEAF)
    dcc[idx].status |= BSTAT_LEAF;
  /* Set capitalization the way they want it */
  noshare = 1;
  change_handle(dcc[idx].user, par);
  noshare = 0;
  strcpy(dcc[idx].nick, par);
}
Beispiel #27
0
	void SendLogout(User *u)
	{
		BotInfo *ns = findbot(Config->NickServ);
		ircdproto->SendMode(ns, u, "+d 1");
	}
Beispiel #28
0
	void SendLogin(User *u)
	{
		BotInfo *ns = findbot(Config->NickServ);
		ircdproto->SendMode(ns, u, "+d %d", u->timestamp);
	}
Beispiel #29
0
bool IRCdMessage::OnPrivmsg(const Anope::string &source, const std::vector<Anope::string> &params)
{
	const Anope::string &receiver = params.size() > 0 ? params[0] : "";
	Anope::string message = params.size() > 1 ? params[1] : "";

	/* Messages from servers can happen on some IRCds, check for . */
	if (source.empty() || receiver.empty() || message.empty() || source.find('.') != Anope::string::npos)
		return true;

	User *u = finduser(source);

	if (!u)
	{
		Log() << message << ": user record for " << source << " not found";

		BotInfo *bi = findbot(receiver);
		if (bi)
			ircdproto->SendMessage(bi, source, "%s", "Internal error - unable to process request.");

		return true;
	}

	if (receiver[0] == '#')
	{
		Channel *c = findchan(receiver);
		if (c)
		{
			FOREACH_MOD(I_OnPrivmsg, OnPrivmsg(u, c, message));
		}
	}
	else
	{
		/* If a server is specified (nick@server format), make sure it matches
		 * us, and strip it off. */
		Anope::string botname = receiver;
		size_t s = receiver.find('@');
		if (s != Anope::string::npos)
		{
			Anope::string servername(receiver.begin() + s + 1, receiver.end());
			botname = botname.substr(0, s);
			if (!servername.equals_ci(Config->ServerName))
				return true;
		}
		else if (Config->UseStrictPrivMsg)
		{
			BotInfo *bi = findbot(receiver);
			if (!bi)
				return true;
			Log(LOG_DEBUG) << "Ignored PRIVMSG without @ from " << source;
			u->SendMessage(bi, _("\"/msg %s\" is no longer supported.  Use \"/msg %s@%s\" or \"/%s\" instead."), receiver.c_str(), receiver.c_str(), Config->ServerName.c_str(), receiver.c_str());
			return true;
		}

		BotInfo *bi = findbot(botname);

		if (bi)
		{
			EventReturn MOD_RESULT;
			FOREACH_RESULT(I_OnBotPrivmsg, OnBotPrivmsg(u, bi, message));
			if (MOD_RESULT == EVENT_STOP)
				return true;

			if (message[0] == '\1' && message[message.length() - 1] == '\1')
			{
				if (message.substr(0, 6).equals_ci("\1PING "))
				{
					Anope::string buf = message;
					buf.erase(buf.begin());
					buf.erase(buf.end() - 1);
					ircdproto->SendCTCP(bi, u->nick, "%s", buf.c_str());
				}
				else if (message.substr(0, 9).equals_ci("\1VERSION\1"))
				{
					Module *enc = ModuleManager::FindFirstOf(ENCRYPTION);
					ircdproto->SendCTCP(bi, u->nick, "VERSION Anope-%s %s :%s - (%s) -- %s", Anope::Version().c_str(), Config->ServerName.c_str(), ircd->name, enc ? enc->name.c_str() : "unknown", Anope::VersionBuildString().c_str());
				}
				return true;
			}
			
			bi->OnMessage(u, message);
		}
	}

	return true;
}
Beispiel #30
0
	void AddSession(User *u, bool exempt)
	{
		Session *session = this->ss.FindSession(u->host);

		if (session)
		{
			bool kill = false;
			if (Config->DefSessionLimit && session->count >= Config->DefSessionLimit)
			{
				kill = true;
				Exception *exception = this->ss.FindException(u);
				if (exception)
				{
					kill = false;
					if (exception->limit && session->count >= exception->limit)
						kill = true;
				}
			}

			/* Previously on IRCds that send a QUIT (InspIRCD) when a user is killed, the session for a host was
			 * decremented in do_quit, which caused problems and fixed here
			 *
			 * Now, we create the user struture before calling this to fix some user tracking issues,
			 * so we must increment this here no matter what because it will either be
			 * decremented in do_kill or in do_quit - Adam
			 */
			++session->count;
	
			if (kill && !exempt)
			{
				BotInfo *bi = findbot(Config->OperServ);
				if (bi)
				{
					if (!Config->SessionLimitExceeded.empty())
						u->SendMessage(bi, Config->SessionLimitExceeded.c_str(), u->host.c_str());
					if (!Config->SessionLimitDetailsLoc.empty())
						u->SendMessage(bi, "%s", Config->SessionLimitDetailsLoc.c_str());
				}

				u->Kill(Config->OperServ, "Session limit exceeded");

				++session->hits;
				if (Config->MaxSessionKill && session->hits >= Config->MaxSessionKill && akills)
				{
					const Anope::string &akillmask = "*@" + u->host;
					XLine *x = new XLine(akillmask, Config->OperServ, Anope::CurTime + Config->SessionAutoKillExpiry, "Session limit exceeded", XLineManager::GenerateUID());
					akills->AddXLine(x);
					akills->Send(NULL, x);
					if (bi)
						ircdproto->SendGlobops(bi, "Added a temporary AKILL for \2%s\2 due to excessive connections", akillmask.c_str());
				}
			}
		}
		else
		{
			session = new Session();
			session->host = u->host;
			session->count = 1;
			session->hits = 0;

			this->ss.AddSession(session);
		}
	}