1
0
mirror of https://github.com/anope/anope.git synced 2026-06-22 00:36:36 +02:00

Compare commits

...

55 Commits

Author SHA1 Message Date
Adam 4ccc478830 Anope 2.0.0 Release 2014-03-23 08:58:02 -04:00
Adam 100ecbb9be Update version.log 2014-03-23 08:57:19 -04:00
Adam cdf636e696 Regen langauge files 2014-03-23 08:57:08 -04:00
Robby- 45878bf182 SASL: Also disallow suspended nicks to login using EXTERNAL mechanism. Improve the log message for failed logins. 2014-03-22 21:14:02 +01:00
Adam f1bec3999d Do not allow SASL login to suspended nicks 2014-03-22 07:21:22 -04:00
Adam a259244297 Make bouncymodes harder to trigger by only bumping server modcount when something changes 2014-03-20 10:53:27 -04:00
Adam c1da009de3 Show a better log message when disconnecting from the uplink 2014-03-19 02:40:48 -04:00
Robby- 4f412bc213 cs_set_misc: Add missing override capability for services operators, and logging. 2014-03-19 03:05:54 +01:00
Robby- 1882916dc4 Update the dutch language file. 2014-03-17 01:15:28 +01:00
Robby- f436ce9912 m_ssl_gnutls: Fix deprecation warnings when using newer GnuTLS versions. 2014-03-17 00:58:51 +01:00
Adam ef9729fb02 Mark all channels as syncing when we connect to our uplink. They will
finish syncing later when the uplink syncs. Normally the channel state
is fully synced here anyway, except if we do not know the modes the
uplink has yet.

Also fix a related issue with resetting chanels and bouncing modes on
our clients, if this is done prior to knowing which modes exist it would
silently fail.
2014-03-14 22:13:04 -04:00
Adam 296a75f2a9 Do not allow users to add certs that other users are using. Only allow adding certfps if the user is using it. 2014-03-13 20:07:50 -04:00
Adam bce7237d9f Set LDAP_OPT_NETWORK_TIMEOUT to 0 in m_ldap to prevent the asynchronous
library cals from blocking...

Fix multiple possible null pointer derefs if modules pass null
interfaces (none currently do, but it is allowed)

Fix memory leak from results when services are destructed

Timeout queries that never come back.
2014-03-11 09:45:34 -04:00
Robby- 85834e19dc Update the dutch language file.
ns_maxemail: Bold code 2 -> 002.
2014-03-10 22:30:41 +01:00
Adam ca6b3723a9 Merge pull request #64 from ShutterQuick/2.0+hsgroupsync
2.0+hsgroupsync
2014-03-10 07:32:24 -04:00
Adam 23b1086072 Merge pull request #63 from alexbarton/ngircd-fix-KILL
ngircd protocol module: really kill users
2014-03-10 07:31:34 -04:00
Adam 860deb14ce Do not send unregistered notice to users who are logged in, even if their nick isn't registered 2014-03-10 07:26:09 -04:00
Adam 62885fa462 Set nickserv's modesonid on login too 2014-03-10 05:04:25 -04:00
Adam 3fef01e35b Fix compile error in m_sasl_dh-aes and m_sasl_dh-blowfish on unusually old g++ versions 2014-03-10 04:56:17 -04:00
Adam b0597e35ec Do not allow nickserv/ungroup to bypass ns_maxemail, and allow opers to bypass ns_maxemail 2014-03-10 04:31:08 -04:00
Adam 8d1ad6fbe5 Make nickserv/glist show the correct expire time for unconfirmed nicks 2014-03-09 22:59:16 -04:00
Adam 750569201a Add missing space to session exception expiration message 2014-03-09 22:56:25 -04:00
Adam 1a1a781b72 Remove mail:restrict as it is no longer useful. Changes nickserv/resetpass default to allow normal users to use it. 2014-03-09 10:07:13 -04:00
DukePyrolator 4b5ce8a972 irc2sql: removed the currentusers field from the chan table, keeping it updated on each join/part eats too many ressources 2014-03-09 04:55:35 +01:00
Daniel Vassdal 98cfdd26c4 ns_group: Don't require a nick param when logged in 2014-03-06 04:55:30 -08:00
Daniel Vassdal 051a42b547 hs_group: Allow automatic HS GROUP-ing on NS GROUP, and allow vhosts to be per account rather than nick. 2014-03-06 04:55:30 -08:00
Adam 220e278213 Open database files using std::ios_base::binary in db_flatfile, which Windows can require 2014-03-05 20:23:44 -05:00
Alexander Barton 547fe0da1a ngircd protocol module: really kill users
ngIRCd doesn't send a QUIT for each user KILL'ed, so kill them immediately.
2014-03-05 10:26:54 +01:00
Adam 09bec79b47 Fix 2 crashes from removing the permanent channel mode from channels which do not exist 2014-03-04 04:15:32 -05:00
Adam 55a5affcb8 Do not allow guest nicks to exceed nicklen, and use a default enforcer ident/host if none is provided 2014-03-04 04:15:32 -05:00
Robby- a8b4297023 Update the dutch language file. 2014-03-03 19:20:56 +01:00
Adam 5969362425 When unserializing channels with persist, set their ts=now. If we are supposed to lower it later we will then. 2014-03-01 22:41:45 -05:00
Adam 3ceae33b16 Convert limit and key mlocks in db_old 2014-03-01 21:56:26 -05:00
Adam 5de4c1fc97 Set +x on plexus when vhosts are activated, fix desync from /hs off 2014-03-01 21:40:47 -05:00
Adam fd109048dd Make db_old load entrymsg 2014-03-01 21:20:32 -05:00
Adam a0747516ce Export interface for cs_entrymsg 2014-03-01 21:20:18 -05:00
Adam 605e1f2a03 Make chanserv/invite show who invited you 2014-03-01 21:12:27 -05:00
Adam dc23c58869 Fix botserv help to show the correct fantasy characters 2014-03-01 21:11:58 -05:00
Adam b7e646ec83 Allow opers with chanserv/administration to use fantasy, even if they don't have the access for it 2014-03-01 20:02:17 -05:00
Adam 4d54358745 When unserializating channels and persist is set, only assign chanserv if the perm channel mode doesnt exist 2014-03-01 19:59:40 -05:00
Adam ed0882ec04 Do not enforce mlock when enforcing mlock 2014-03-01 18:39:10 -05:00
Adam 526c4e4659 Check modes after applying mlocks in db_old 2014-03-01 18:38:14 -05:00
Adam b70f72bf2b Do not allow changing the email of unconfirmed accounts 2014-03-01 04:31:52 -05:00
Adam 2ad4c1906e Fix incorrect comment in modules.example.conf 2014-03-01 04:27:45 -05:00
Adam 049760cc7e Allow svsjoin/svspart on yourself 2014-02-28 00:30:35 -05:00
Adam e2ecec31b5 Hybrid does not let us add resvs as a server, but the core expects to be able to qline bot nicks before introducing the bots as a way to prevent collisions, so try harder to find a valid bot to send resvs on startup 2014-02-27 23:21:50 -05:00
Adam fee016bb84 Handle nick collisions somewhat instead of blindly overwriting the nicks
in memory, which does weird things.

For fun different ircds implement this differently (Unreal compares
timestamps, TS6 compares timestamps and user username/host), and whether
or not we get a kill for our user also varies, so just kill everyone.

This can't really happen anyway with properly set qlines, only if
services haven't yet set the qlines, or possibly in a bot add/nick
user introduce race, or with enforcers, which not many ircds require.
2014-02-27 22:42:54 -05:00
Adam d24fb03917 Allow registration=mail forceemail=false to work, and simply give fully registered accounts to people who do not provide an email to nickserv/register 2014-02-27 04:49:28 -05:00
Adam 5adc8bfefc Do not take modes from users in channels with secureops off if we are always lowering channels timestamps to their creations 2014-02-27 04:48:48 -05:00
Adam abcf0cde5a Remove unreachable code in config.cpp, this error is caught earlier 2014-02-26 19:32:25 -05:00
Adam 8f3bd314ed Fix not detecting eols in the config reader when the end of the line is the end of a multiline comment 2014-02-26 19:26:50 -05:00
Adam e2d456d4ce Do not setuid/gid down until after modules are loaded 2014-02-26 19:24:32 -05:00
Adam 96202ae545 Log successful SASL auths 2014-02-24 22:23:12 -05:00
H7-25 2b0229d4e2 Update the italian language file 2014-02-25 03:22:55 +01:00
Adam beaa3196b3 Update Spanish translation, from Isaac Fontal <i_fontal@hotmail.com> 2014-02-24 16:14:40 -05:00
68 changed files with 5012 additions and 4610 deletions
+2 -14
View File
@@ -780,7 +780,7 @@ log
* memoserv/sendall memoserv/staff
*
* nickserv/getpass nickserv/getemail nickserv/suspend nickserv/ajoin
* nickserv/resetpass nickserv/list
* nickserv/list
*
* nickserv/saset/autoop nickserv/saset/email nickserv/saset/greet nickserv/saset/password
* nickserv/saset/display nickserv/saset/kill nickserv/saset/language nickserv/saset/message
@@ -826,7 +826,7 @@ opertype
inherits = "Helper, Another Helper"
/* What commands (see above) this opertype may use */
commands = "chanserv/list chanserv/suspend chanserv/topic memoserv/staff nickserv/list nickserv/resetpass nickserv/suspend operserv/mode operserv/chankill operserv/akill operserv/session operserv/modinfo operserv/sqline operserv/oper operserv/kick operserv/ignore operserv/snline"
commands = "chanserv/list chanserv/suspend chanserv/topic memoserv/staff nickserv/list nickserv/suspend operserv/mode operserv/chankill operserv/akill operserv/session operserv/modinfo operserv/sqline operserv/oper operserv/kick operserv/ignore operserv/snline"
/* What privs (see above) this opertype has */
privs = "chanserv/auspex chanserv/no-register-limit memoserv/* nickserv/auspex nickserv/confirm"
@@ -952,18 +952,6 @@ mail
*/
sendfrom = "services@localhost.net"
/*
* If set, RESETPASS will be restricted to services operators with access to
* nickserv/resetpass in their opertype:commands.
* This directive is optional.
*
* WARNING: If you choose to not enable this option, you should limit the
* number of processes that the services user can have at a time (you can
* create a special user for this; remember to NEVER launch Services as
* root).
*/
restrict = yes
/*
* This controls the minimum amount of time a user must wait before sending
* another e-mail after they have sent one. It also controls the minimum time
+14 -1
View File
@@ -103,7 +103,20 @@ command { service = "HostServ"; name = "DELALL"; command = "hostserv/delall"; pe
*
* Used for grouping one vHost to many nicks.
*/
module { name = "hs_group" }
module
{
name = "hs_group"
/*
* Upon nickserv/group, this option syncs the nick's main vHost to the grouped nick.
*/
syncongroup = false
/*
* This makes vhosts act as if they are per account.
*/
synconset = false
}
command { service = "HostServ"; name = "GROUP"; command = "hostserv/group"; }
/*
+1 -1
View File
@@ -519,7 +519,7 @@ module { name = "help" }
#module { name = "m_sasl_dh-aes" }
/*
* m_sasl_dh-aes [EXTRA]
* m_sasl_dh-blowfish [EXTRA]
*
* Add the DH-BLOWFISH mechanism to SASL.
* Requires m_sasl to be loaded.
+3 -3
View File
@@ -306,7 +306,7 @@ module
* The maximum number of entries allowed on a nickname's certificate fingerprint list.
* The default is 5. This number cannot be set to 0.
*/
accessmax = 5
max = 5
}
command { service = "NickServ"; name = "CERT"; command = "nickserv/cert"; }
@@ -640,7 +640,7 @@ command { service = "NickServ"; name = "UPDATE"; command = "nickserv/update"; }
* Limits how many times the same email address may be used in Anope
* to register accounts.
*/
module
#module
{
name = "ns_maxemail"
@@ -649,5 +649,5 @@ module
* commented, there will be no limit enforced when registering new accounts or using
* /msg NickServ SET EMAIL.
*/
#maxemails = 1
maxemails = 1
}
+55
View File
@@ -1,3 +1,58 @@
Revision cdf636e - Sun, 23 Mar 2014 08:57:08 -0400 - Regen langauge files
Revision 45878bf - Sat, 22 Mar 2014 21:14:02 +0100 - SASL: Also disallow suspended nicks to login using EXTERNAL mechanism. Improve the log message for failed logins.
Revision f1bec39 - Sat, 22 Mar 2014 07:21:22 -0400 - Do not allow SASL login to suspended nicks
Revision a259244 - Thu, 20 Mar 2014 10:53:27 -0400 - Make bouncymodes harder to trigger by only bumping server modcount when something changes
Revision c1da009 - Wed, 19 Mar 2014 02:40:48 -0400 - Show a better log message when disconnecting from the uplink
Revision 4f412bc - Wed, 19 Mar 2014 03:05:54 +0100 - cs_set_misc: Add missing override capability for services operators, and logging.
Revision 1882916 - Mon, 17 Mar 2014 01:15:28 +0100 - Update the dutch language file.
Revision f436ce9 - Mon, 17 Mar 2014 00:58:51 +0100 - m_ssl_gnutls: Fix deprecation warnings when using newer GnuTLS versions.
Revision ef9729f - Fri, 14 Mar 2014 22:13:04 -0400 - Mark all channels as syncing when we connect to our uplink. They will finish syncing later when the uplink syncs. Normally the channel state is fully synced here anyway, except if we do not know the modes the uplink has yet.
Revision 296a75f - Thu, 13 Mar 2014 20:07:50 -0400 - Do not allow users to add certs that other users are using. Only allow adding certfps if the user is using it.
Revision bce7237 - Tue, 11 Mar 2014 09:45:34 -0400 - Set LDAP_OPT_NETWORK_TIMEOUT to 0 in m_ldap to prevent the asynchronous library cals from blocking...
Revision 85834e1 - Mon, 10 Mar 2014 22:30:41 +0100 - Update the dutch language file. ns_maxemail: Bold code 2 -> 002.
Revision ca6b372 - Mon, 10 Mar 2014 07:32:24 -0400 - Merge pull request #64 from ShutterQuick/2.0+hsgroupsync
Revision 23b1086 - Mon, 10 Mar 2014 07:31:34 -0400 - Merge pull request #63 from alexbarton/ngircd-fix-KILL
Revision 860deb1 - Mon, 10 Mar 2014 07:26:09 -0400 - Do not send unregistered notice to users who are logged in, even if their nick isn't registered
Revision 62885fa - Mon, 10 Mar 2014 05:04:25 -0400 - Set nickserv's modesonid on login too
Revision 3fef01e - Mon, 10 Mar 2014 04:56:17 -0400 - Fix compile error in m_sasl_dh-aes and m_sasl_dh-blowfish on unusually old g++ versions
Revision b0597e3 - Mon, 10 Mar 2014 04:31:08 -0400 - Do not allow nickserv/ungroup to bypass ns_maxemail, and allow opers to bypass ns_maxemail
Revision 8d1ad6f - Sun, 9 Mar 2014 22:59:16 -0400 - Make nickserv/glist show the correct expire time for unconfirmed nicks
Revision 7505692 - Sun, 9 Mar 2014 22:56:25 -0400 - Add missing space to session exception expiration message
Revision 1a1a781 - Sun, 9 Mar 2014 10:07:13 -0400 - Remove mail:restrict as it is no longer useful. Changes nickserv/resetpass default to allow normal users to use it.
Revision 4b5ce8a - Sun, 9 Mar 2014 04:55:35 +0100 - irc2sql: removed the currentusers field from the chan table, keeping it updated on each join/part eats too many ressources
Revision 98cfdd2 - Thu, 6 Mar 2014 04:55:30 -0800 - ns_group: Don't require a nick param when logged in
Revision 051a42b - Thu, 6 Mar 2014 04:55:30 -0800 - hs_group: Allow automatic HS GROUP-ing on NS GROUP, and allow vhosts to be per account rather than nick.
Revision 220e278 - Wed, 5 Mar 2014 20:23:44 -0500 - Open database files using std::ios_base::binary in db_flatfile, which Windows can require
Revision 547fe0d - Wed, 5 Mar 2014 10:26:54 +0100 - ngircd protocol module: really kill users
Revision 09bec79 - Tue, 4 Mar 2014 04:15:32 -0500 - Fix 2 crashes from removing the permanent channel mode from channels which do not exist
Revision 55a5aff - Tue, 4 Mar 2014 04:15:32 -0500 - Do not allow guest nicks to exceed nicklen, and use a default enforcer ident/host if none is provided
Revision a8b4297 - Mon, 3 Mar 2014 19:20:56 +0100 - Update the dutch language file.
Revision 5969362 - Sat, 1 Mar 2014 22:41:45 -0500 - When unserializing channels with persist, set their ts=now. If we are supposed to lower it later we will then.
Revision 3ceae33 - Sat, 1 Mar 2014 21:56:26 -0500 - Convert limit and key mlocks in db_old
Revision 5de4c1f - Sat, 1 Mar 2014 21:40:47 -0500 - Set +x on plexus when vhosts are activated, fix desync from /hs off
Revision fd10904 - Sat, 1 Mar 2014 21:20:32 -0500 - Make db_old load entrymsg
Revision a074751 - Sat, 1 Mar 2014 21:20:18 -0500 - Export interface for cs_entrymsg
Revision 605e1f2 - Sat, 1 Mar 2014 21:12:27 -0500 - Make chanserv/invite show who invited you
Revision dc23c58 - Sat, 1 Mar 2014 21:11:58 -0500 - Fix botserv help to show the correct fantasy characters
Revision b7e646e - Sat, 1 Mar 2014 20:02:17 -0500 - Allow opers with chanserv/administration to use fantasy, even if they don't have the access for it
Revision 4d54358 - Sat, 1 Mar 2014 19:59:40 -0500 - When unserializating channels and persist is set, only assign chanserv if the perm channel mode doesnt exist
Revision ed0882e - Sat, 1 Mar 2014 18:39:10 -0500 - Do not enforce mlock when enforcing mlock
Revision 526c4e4 - Sat, 1 Mar 2014 18:38:14 -0500 - Check modes after applying mlocks in db_old
Revision b70f72b - Sat, 1 Mar 2014 04:31:52 -0500 - Do not allow changing the email of unconfirmed accounts
Revision 2ad4c19 - Sat, 1 Mar 2014 04:27:45 -0500 - Fix incorrect comment in modules.example.conf
Revision 049760c - Fri, 28 Feb 2014 00:30:35 -0500 - Allow svsjoin/svspart on yourself
Revision e2ecec3 - Thu, 27 Feb 2014 23:21:50 -0500 - Hybrid does not let us add resvs as a server, but the core expects to be able to qline bot nicks before introducing the bots as a way to prevent collisions, so try harder to find a valid bot to send resvs on startup
Revision fee016b - Thu, 27 Feb 2014 22:42:54 -0500 - Handle nick collisions somewhat instead of blindly overwriting the nicks in memory, which does weird things.
Revision d24fb03 - Thu, 27 Feb 2014 04:49:28 -0500 - Allow registration=mail forceemail=false to work, and simply give fully registered accounts to people who do not provide an email to nickserv/register
Revision 5adc8bf - Thu, 27 Feb 2014 04:48:48 -0500 - Do not take modes from users in channels with secureops off if we are always lowering channels timestamps to their creations
Revision abcf0cd - Wed, 26 Feb 2014 19:32:25 -0500 - Remove unreachable code in config.cpp, this error is caught earlier
Revision 8f3bd31 - Wed, 26 Feb 2014 19:26:50 -0500 - Fix not detecting eols in the config reader when the end of the line is the end of a multiline comment
Revision e2d456d - Wed, 26 Feb 2014 19:24:32 -0500 - Do not setuid/gid down until after modules are loaded
Revision 96202ae - Mon, 24 Feb 2014 22:23:12 -0500 - Log successful SASL auths
Revision 2b0229d - Tue, 25 Feb 2014 03:22:55 +0100 - Update the italian language file
Revision beaa319 - Mon, 24 Feb 2014 16:14:40 -0500 - Update Spanish translation, from Isaac Fontal <i_fontal@hotmail.com>
Revision b6d771a - Mon, 24 Feb 2014 00:31:07 -0500 - Anope 2.0.0-rc4 Release
Revision d3ed756 - Mon, 24 Feb 2014 00:30:57 -0500 - Update version.log (why do we keep this around?)
Revision f830884 - Mon, 24 Feb 2014 00:30:47 -0500 - Package dlls in src/win32 on Windows
Revision 1dfdf36 - Mon, 24 Feb 2014 00:06:38 -0500 - Fix m_ssl_gnutls to send its cert. Most of this is from Attila.
Revision 4ac3ade - Sun, 23 Feb 2014 23:08:35 -0500 - Use a more reliable way to detect if services are running in anoperc
+1
View File
@@ -3,6 +3,7 @@ Anope Version 2.0.0
options:passlen, enforceruser, enforcerhost, releasetimeout, and guestnickprefix moved to nickserv's module configuration
options:hideregisteredcommands added
m_ssl renamed to m_ssl_openssl
mail:restrict removed
Anope Version 1.9.9
-------------------
+2
View File
@@ -60,6 +60,8 @@ class CoreExport BotInfo : public User, public Serializable
void GenerateUID();
void OnKill();
/** Change the nickname for the bot.
* @param newnick The nick to change to
*/
+1 -1
View File
@@ -1010,7 +1010,7 @@ class CoreExport Module : public Extensible
* mostly to ensure mlock/+r are set.
* @param c The channel
*/
virtual void OnCheckModes(Channel *c) { throw NotImplementedException(); }
virtual void OnCheckModes(Reference<Channel> &c) { throw NotImplementedException(); }
/** Called when a channel is synced.
* Channels are synced after a sjoin is finished processing
+35
View File
@@ -0,0 +1,35 @@
/*
* (C) 2003-2014 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
*/
struct EntryMsg
{
Anope::string chan;
Anope::string creator;
Anope::string message;
time_t when;
virtual ~EntryMsg() { }
protected:
EntryMsg() { }
};
struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >
{
protected:
EntryMessageList() : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { }
public:
virtual ~EntryMessageList()
{
for (unsigned i = (*this)->size(); i > 0; --i)
delete (*this)->at(i - 1);
}
virtual EntryMsg* Create() = 0;
};
+10 -2
View File
@@ -86,12 +86,13 @@ namespace SASL
return;
NickAlias *na = NickAlias::Find(GetAccount());
if (!na)
if (!na || na->nc->HasExt("NS_SUSPENDED"))
return OnFail();
Session *s = sasl->GetSession(uid);
if (s)
{
Log(Config->GetClient("NickServ")) << "A user identified to account " << this->GetAccount() << " using SASL";
sasl->Succeed(s, na->nc);
delete s;
}
@@ -109,7 +110,14 @@ namespace SASL
delete s;
}
Log(Config->GetClient("NickServ")) << "A user failed to identify for account " << this->GetAccount() << " using SASL";
Anope::string accountstatus;
NickAlias *na = NickAlias::Find(GetAccount());
if (!na)
accountstatus = "nonexistent ";
else if (na->nc->HasExt("NS_SUSPENDED"))
accountstatus = "suspended ";
Log(Config->GetClient("NickServ")) << "A user failed to identify for " << accountstatus << "account " << this->GetAccount() << " using SASL";
}
};
}
+2
View File
@@ -111,6 +111,8 @@ class CoreExport IRCDProto : public Service
virtual void SendSQLine(User *, const XLine *x) { }
virtual void SendSQLineDel(const XLine *x) { }
virtual void SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason);
/** Kills a user
* @param source Who is doing the kill
* @param user The user to be killed
+5 -3
View File
@@ -92,6 +92,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
/* Last time this user sent an email */
time_t lastmail;
protected:
/** Create a new user object, initialising necessary fields and
* adds it to the hash
*
@@ -102,19 +103,20 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe
* @param sip The ip of the user
* @param sserver The server of the user
* @param srealname The realname/gecos of teh user
* @param ssignon User's timestamp
* @param ts User's timestamp
* @param smodes User's modes
* @param suid The unique identifier of the user.
* @param nc The account the user is identified as, if any
*/
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
protected:
/** Destroy a user.
*/
virtual ~User();
public:
static User* OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc);
/** Update the nickname of a user record accordingly, should be
* called from ircd protocol.
* @param newnick The new username
+330 -324
View File
File diff suppressed because it is too large Load Diff
+332 -323
View File
File diff suppressed because it is too large Load Diff
+334 -334
View File
File diff suppressed because it is too large Load Diff
+631 -707
View File
File diff suppressed because it is too large Load Diff
+331 -321
View File
File diff suppressed because it is too large Load Diff
+330 -324
View File
File diff suppressed because it is too large Load Diff
+337 -327
View File
File diff suppressed because it is too large Load Diff
+330 -326
View File
File diff suppressed because it is too large Load Diff
+330 -324
View File
File diff suppressed because it is too large Load Diff
+330 -324
View File
File diff suppressed because it is too large Load Diff
+331 -324
View File
File diff suppressed because it is too large Load Diff
+330 -324
View File
File diff suppressed because it is too large Load Diff
+32 -29
View File
@@ -10,27 +10,27 @@
*/
#include "module.h"
#include "modules/cs_entrymsg.h"
struct EntryMsg : Serializable
struct EntryMsgImpl : EntryMsg, Serializable
{
Serialize::Reference<ChannelInfo> ci;
Anope::string creator;
Anope::string message;
time_t when;
EntryMsg(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime) : Serializable("EntryMsg")
EntryMsgImpl() : Serializable("EntryMsg")
{
this->ci = c;
}
EntryMsgImpl(ChannelInfo *c, const Anope::string &cname, const Anope::string &cmessage, time_t ct = Anope::CurTime) : Serializable("EntryMsg")
{
this->chan = c->name;
this->creator = cname;
this->message = cmessage;
this->when = ct;
}
~EntryMsg();
~EntryMsgImpl();
void Serialize(Serialize::Data &data) const anope_override
{
data["ci"] << this->ci->name;
data["ci"] << this->chan;
data["creator"] << this->creator;
data["message"] << this->message;
data.SetType("when", Serialize::Data::DT_INT); data["when"] << this->when;
@@ -39,30 +39,33 @@ struct EntryMsg : Serializable
static Serializable* Unserialize(Serializable *obj, Serialize::Data &data);
};
struct EntryMessageList : Serialize::Checker<std::vector<EntryMsg *> >
struct EntryMessageListImpl : EntryMessageList
{
EntryMessageList(Extensible *) : Serialize::Checker<std::vector<EntryMsg *> >("EntryMsg") { }
EntryMessageListImpl(Extensible *) { }
~EntryMessageList()
EntryMsg* Create() anope_override
{
for (unsigned i = (*this)->size(); i > 0; --i)
delete (*this)->at(i - 1);
return new EntryMsgImpl();
}
};
EntryMsg::~EntryMsg()
EntryMsgImpl::~EntryMsgImpl()
{
ChannelInfo *ci = ChannelInfo::Find(this->chan);
if (!ci)
return;
EntryMessageList *messages = ci->GetExt<EntryMessageList>("entrymsg");
if (messages)
{
std::vector<EntryMsg *>::iterator it = std::find((*messages)->begin(), (*messages)->end(), this);
if (it != (*messages)->end())
(*messages)->erase(it);
}
if (!messages)
return;
std::vector<EntryMsg *>::iterator it = std::find((*messages)->begin(), (*messages)->end(), this);
if (it != (*messages)->end())
(*messages)->erase(it);
}
Serializable* EntryMsg::Unserialize(Serializable *obj, Serialize::Data &data)
Serializable* EntryMsgImpl::Unserialize(Serializable *obj, Serialize::Data &data)
{
Anope::string sci, screator, smessage;
time_t swhen;
@@ -77,8 +80,8 @@ Serializable* EntryMsg::Unserialize(Serializable *obj, Serialize::Data &data)
if (obj)
{
EntryMsg *msg = anope_dynamic_static_cast<EntryMsg *>(obj);
msg->ci = ci;
EntryMsgImpl *msg = anope_dynamic_static_cast<EntryMsgImpl *>(obj);
msg->chan = ci->name;
data["creator"] >> msg->creator;
data["message"] >> msg->message;
data["when"] >> msg->when;
@@ -89,7 +92,7 @@ Serializable* EntryMsg::Unserialize(Serializable *obj, Serialize::Data &data)
data["when"] >> swhen;
EntryMsg *m = new EntryMsg(ci, screator, smessage, swhen);
EntryMsgImpl *m = new EntryMsgImpl(ci, screator, smessage, swhen);
(*messages)->push_back(m);
return m;
}
@@ -139,7 +142,7 @@ class CommandEntryMessage : public Command
source.Reply(_("The entry message list for \002%s\002 is full."), ci->name.c_str());
else
{
(*messages)->push_back(new EntryMsg(ci, source.GetNick(), message));
(*messages)->push_back(new EntryMsgImpl(ci, source.GetNick(), message));
Log(source.IsFounder(ci) ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to add a message";
source.Reply(_("Entry message added to \002%s\002"), ci->name.c_str());
}
@@ -257,13 +260,13 @@ class CommandEntryMessage : public Command
class CSEntryMessage : public Module
{
CommandEntryMessage commandentrymsg;
ExtensibleItem<EntryMessageList> eml;
ExtensibleItem<EntryMessageListImpl> eml;
Serialize::Type entrymsg_type;
public:
CSEntryMessage(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandentrymsg(this),
eml(this, "entrymsg"), entrymsg_type("EntryMsg", EntryMsg::Unserialize)
eml(this, "entrymsg"), entrymsg_type("EntryMsg", EntryMsgImpl::Unserialize)
{
}
+2 -1
View File
@@ -73,13 +73,14 @@ class CommandCSInvite : public Command
if (u2 != u)
{
source.Reply(_("\002%s\002 has been invited to \002%s\002."), u2->nick.c_str(), c->name.c_str());
u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002 by \002%s\002."), c->name.c_str(), source.GetNick().c_str());
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
}
else
{
u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci);
}
u2->SendMessage(ci->WhoSends(), _("You have been invited to \002%s\002."), c->name.c_str());
}
}
+8 -8
View File
@@ -902,9 +902,9 @@ class CSMode : public Module
}
}
void OnCheckModes(Channel *c) anope_override
void OnCheckModes(Reference<Channel> &c) anope_override
{
if (!c->ci)
if (!c || !c->ci)
return;
ModeLocks *locks = modelocks.Get(c->ci);
@@ -919,9 +919,9 @@ class CSMode : public Module
if (cm->type == MODE_REGULAR)
{
if (!c->HasMode(cm->name) && ml->set)
c->SetMode(NULL, cm);
c->SetMode(NULL, cm, "", false);
else if (c->HasMode(cm->name) && !ml->set)
c->RemoveMode(NULL, cm);
c->RemoveMode(NULL, cm, "", false);
}
else if (cm->type == MODE_PARAM)
{
@@ -932,21 +932,21 @@ class CSMode : public Module
c->GetParam(cm->name, param);
if (!c->HasMode(cm->name) || (!param.empty() && !ml->param.empty() && !param.equals_cs(ml->param)))
c->SetMode(NULL, cm, ml->param);
c->SetMode(NULL, cm, ml->param, false);
}
else
{
if (c->HasMode(cm->name))
c->RemoveMode(NULL, cm);
c->RemoveMode(NULL, cm, "", false);
}
}
else if (cm->type == MODE_LIST || cm->type == MODE_STATUS)
{
if (ml->set)
c->SetMode(NULL, cm, ml->param);
c->SetMode(NULL, cm, ml->param, false);
else
c->RemoveMode(NULL, cm, ml->param);
c->RemoveMode(NULL, cm, ml->param, false);
}
}
}
+20 -16
View File
@@ -1163,18 +1163,27 @@ class CSSet : public Module
return;
bool created;
Channel *c = Channel::FindOrCreate(ci->name, created, ci->time_registered);
if (!ci->bi)
{
BotInfo *ChanServ = Config->GetClient("ChanServ");
if (ChanServ)
ChanServ->Assign(NULL, ci);
}
Channel *c = Channel::FindOrCreate(ci->name, created);
if (ci->bi && !c->FindUser(ci->bi))
ChannelMode *cm = ModeManager::FindChannelModeByName("PERM");
if (cm)
{
ChannelStatus status(BotModes());
ci->bi->Join(c, &status);
c->SetMode(NULL, cm);
}
else
{
if (!ci->bi)
{
BotInfo *ChanServ = Config->GetClient("ChanServ");
if (ChanServ)
ChanServ->Assign(NULL, ci);
}
if (ci->bi && !c->FindUser(ci->bi))
{
ChannelStatus status(BotModes());
ci->bi->Join(c, &status);
}
}
if (created)
@@ -1280,12 +1289,6 @@ class CSSet : public Module
{
if (c->ci)
persist.Unset(c->ci);
if (c->CheckDelete())
{
delete c;
return EVENT_STOP;
}
}
if (c->ci && mode->type != MODE_STATUS && !c->syncing && Me->IsSynced())
@@ -1319,6 +1322,7 @@ class CSSet : public Module
if (noautoop.HasExt(chan->ci))
give_modes = false;
if (secureops.HasExt(chan->ci))
// This overrides what chanserv does because it is loaded after chanserv
take_modes = true;
}
}
+3 -1
View File
@@ -116,7 +116,7 @@ class CommandCSSetMisc : public Command
if (MOD_RESULT == EVENT_STOP)
return;
if (MOD_RESULT != EVENT_ALLOW && source.permission.empty() && !source.AccessFor(ci).HasPriv("SET"))
if (MOD_RESULT != EVENT_ALLOW && !source.AccessFor(ci).HasPriv("SET") && source.permission.empty() && !source.HasPriv("chanserv/administration"))
{
source.Reply(ACCESS_DENIED);
return;
@@ -131,11 +131,13 @@ class CommandCSSetMisc : public Command
if (!param.empty())
{
item->Set(ci, CSMiscData(ci, key, param));
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to change it to " << param;
source.Reply(CHAN_SETTING_CHANGED, scommand.c_str(), ci->name.c_str(), params[1].c_str());
}
else
{
item->Unset(ci);
Log(source.AccessFor(ci).HasPriv("SET") ? LOG_COMMAND : LOG_OVERRIDE, source, this, ci) << "to unset it";
source.Reply(CHAN_SETTING_UNSET, scommand.c_str(), ci->name.c_str());
}
}
+37 -3
View File
@@ -13,21 +13,31 @@
class CommandHSGroup : public Command
{
bool setting;
public:
void Sync(const NickAlias *na)
{
if (setting)
return;
if (!na || !na->HasVhost())
return;
setting = true;
for (unsigned i = 0; i < na->nc->aliases->size(); ++i)
{
NickAlias *nick = na->nc->aliases->at(i);
if (nick)
{
nick->SetVhost(na->GetVhostIdent(), na->GetVhostHost(), na->GetVhostCreator());
FOREACH_MOD(OnSetVhost, (nick));
}
}
setting = false;
}
public:
CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0)
CommandHSGroup(Module *creator) : Command(creator, "hostserv/group", 0, 0), setting(false)
{
this->SetDesc(_("Syncs the vhost for all nicks in a group"));
}
@@ -69,12 +79,36 @@ class CommandHSGroup : public Command
class HSGroup : public Module
{
CommandHSGroup commandhsgroup;
bool syncongroup;
bool synconset;
public:
HSGroup(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
commandhsgroup(this)
{
}
void OnSetVhost(NickAlias *na) anope_override
{
if (!synconset)
return;
commandhsgroup.Sync(na);
}
void OnNickGroup(User *u, NickAlias *na) anope_override
{
if (!syncongroup)
return;
commandhsgroup.Sync(na);
}
void OnReload(Configuration::Conf *conf) anope_override
{
Configuration::Block *block = conf->GetModule(this);
syncongroup = block->Get<bool>("syncongroup");
synconset = block->Get<bool>("synconset");
}
};
+31 -24
View File
@@ -148,7 +148,9 @@ struct NSCertListImpl : NSCertList
Anope::string buf;
data["cert"] >> buf;
spacesepstream sep(buf);
c->ClearCert();
for (unsigned i = 0; i < c->certs.size(); ++i)
certmap.erase(c->certs[i]);
c->certs.clear();
while (sep.GetToken(buf))
{
c->certs.push_back(buf);
@@ -161,28 +163,28 @@ struct NSCertListImpl : NSCertList
class CommandNSCert : public Command
{
private:
void DoAdd(CommandSource &source, NickCore *nc, const Anope::string &certfp)
void DoAdd(CommandSource &source, NickCore *nc, Anope::string certfp)
{
NSCertList *cl = nc->Require<NSCertList>("certificates");
unsigned max = Config->GetModule(this->owner)->Get<unsigned>("max", "5");
if (cl->GetCertCount() >= Config->GetModule(this->owner)->Get<unsigned>("accessmax", "5"))
if (cl->GetCertCount() >= max)
{
source.Reply(_("Sorry, the maximum of %d certificate entries has been reached."), Config->GetModule(this->owner)->Get<unsigned>("accessmax"));
source.Reply(_("Sorry, the maximum of %d certificate entries has been reached."), max);
return;
}
if (certfp.empty())
if (source.GetAccount() == nc)
{
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && !cl->FindCert(source.GetUser()->fingerprint))
{
cl->AddCert(source.GetUser()->fingerprint);
Log(LOG_COMMAND, source, this) << "to ADD its current certificate fingerprint " << source.GetUser()->fingerprint;
source.Reply(_("\002%s\002 added to your certificate list."), source.GetUser()->fingerprint.c_str());
}
else
this->OnSyntaxError(source, "ADD");
User *u = source.GetUser();
return;
if (!u || u->fingerprint.empty())
{
source.Reply(_("You are not using a client certificate."));
return;
}
certfp = u->fingerprint;
}
if (cl->FindCert(certfp))
@@ -191,26 +193,31 @@ class CommandNSCert : public Command
return;
}
if (certmap.find(certfp) != certmap.end())
{
source.Reply(_("Fingerprint \002%s\002 is already in use."), certfp.c_str());
return;
}
cl->AddCert(certfp);
Log(nc == source.GetAccount() ? LOG_COMMAND : LOG_ADMIN, source, this) << "to ADD certificate fingerprint " << certfp << " to " << nc->display;
source.Reply(_("\002%s\002 added to %s's certificate list."), certfp.c_str(), nc->display.c_str());
}
void DoDel(CommandSource &source, NickCore *nc, const Anope::string &certfp)
void DoDel(CommandSource &source, NickCore *nc, Anope::string certfp)
{
NSCertList *cl = nc->Require<NSCertList>("certificates");
if (certfp.empty())
{
if (source.GetUser() && !source.GetUser()->fingerprint.empty() && cl->FindCert(source.GetUser()->fingerprint))
{
cl->EraseCert(source.GetUser()->fingerprint);
Log(LOG_COMMAND, source, this) << "to DELETE its current certificate fingerprint " << source.GetUser()->fingerprint;
source.Reply(_("\002%s\002 deleted from your certificate list."), source.GetUser()->fingerprint.c_str());
}
else
this->OnSyntaxError(source, "DEL");
User *u = source.GetUser();
if (u)
certfp = u->fingerprint;
}
if (certfp.empty())
{
this->OnSyntaxError(source, "DEL");
return;
}
@@ -248,7 +255,7 @@ class CommandNSCert : public Command
CommandNSCert(Module *creator) : Command(creator, "nickserv/cert", 1, 3)
{
this->SetDesc(_("Modify the nickname client certificate list"));
this->SetSyntax(_("ADD [\037nickname\037] \037fingerprint\037"));
this->SetSyntax(_("ADD [\037nickname\037] [\037fingerprint\037]"));
this->SetSyntax(_("DEL [\037nickname\037] \037fingerprint\037"));
this->SetSyntax(_("LIST [\037nickname\037]"));
}
+32 -5
View File
@@ -72,10 +72,10 @@ class NSGroupRequest : public IdentifyRequest
class CommandNSGroup : public Command
{
public:
CommandNSGroup(Module *creator) : Command(creator, "nickserv/group", 1, 2)
CommandNSGroup(Module *creator) : Command(creator, "nickserv/group", 0, 2)
{
this->SetDesc(_("Join a group"));
this->SetSyntax(_("\037target\037 \037password\037"));
this->SetSyntax(_("\037[target]\037 \037[password]\037"));
this->AllowUnregistered(true);
this->RequireUser(true);
}
@@ -83,7 +83,23 @@ class CommandNSGroup : public Command
void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
{
User *u = source.GetUser();
const Anope::string &nick = params[0];
Anope::string nick;
if (params.empty())
{
NickCore* core = u->Account();
if (core)
nick = core->display;
}
else
nick = params[0];
if (nick.empty())
{
this->SendSyntax(source);
return;
}
const Anope::string &pass = params.size() > 1 ? params[1] : "";
if (Anope::ReadOnly)
@@ -297,14 +313,25 @@ class CommandNSGList : public Command
ListFormatter list(source.GetAccount());
list.AddColumn(_("Nick")).AddColumn(_("Expires"));
time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire");
time_t nickserv_expire = Config->GetModule("nickserv")->Get<time_t>("expire", "21d"),
unconfirmed_expire = Config->GetModule("nickserv")->Get<time_t>("unconfirmedexpire", "1d");
for (unsigned i = 0; i < nc->aliases->size(); ++i)
{
const NickAlias *na2 = nc->aliases->at(i);
Anope::string expires;
if (na2->HasExt("NS_NO_EXPIRE"))
expires = "Does not expire";
else if (!nickserv_expire || Anope::NoExpire)
;
else if (na2->nc->HasExt("UNCONFIRMED") && unconfirmed_expire)
expires = Anope::strftime(na2->time_registered + unconfirmed_expire, source.GetAccount());
else
expires = Anope::strftime(na2->last_seen + nickserv_expire, source.GetAccount());
ListFormatter::ListEntry entry;
entry["Nick"] = na2->nick;
entry["Expires"] = (na2->HasExt("NS_NO_EXPIRE") || !nickserv_expire || Anope::NoExpire) ? "Does not expire" : Anope::strftime(na2->last_seen + nickserv_expire, source.GetAccount());
entry["Expires"] = expires;
list.AddEntry(entry);
}
+5 -8
View File
@@ -130,12 +130,6 @@ class CommandNSRegister : public Command
return;
}
if (nsregister.equals_ci("mail") && email.empty())
{
source.Reply(_("You must specify an email address."));
return;
}
time_t nickregdelay = Config->GetModule(this->owner)->Get<time_t>("nickregdelay");
time_t reg_delay = Config->GetModule("nickserv")->Get<time_t>("regdelay");
if (u && !u->HasMode("OPER") && nickregdelay && Anope::CurTime - u->timestamp < nickregdelay)
@@ -222,8 +216,11 @@ class CommandNSRegister : public Command
}
else if (nsregister.equals_ci("mail"))
{
nc->Extend<bool>("UNCONFIRMED");
SendRegmail(NULL, na, source.service);
if (!email.empty())
{
nc->Extend<bool>("UNCONFIRMED");
SendRegmail(NULL, na, source.service);
}
}
if (u)
+1 -3
View File
@@ -27,9 +27,7 @@ class CommandNSResetPass : public Command
{
const NickAlias *na;
if (Config->GetBlock("mail")->Get<bool>("restrict") && !source.HasCommand("nickserv/resetpass"))
source.Reply(ACCESS_DENIED);
else if (!(na = NickAlias::Find(params[0])))
if (!(na = NickAlias::Find(params[0])))
source.Reply(NICK_X_NOT_REGISTERED, params[0].c_str());
else if (!na->nc->email.equals_ci(params[1]))
source.Reply(_("Incorrect email address."));
+6
View File
@@ -449,6 +449,12 @@ class CommandNSSetEmail : public Command
}
NickCore *nc = na->nc;
if (nc->HasExt("UNCONFIRMED"))
{
source.Reply(_("You may not change the email of an unconfirmed account."));
return;
}
if (param.empty() && Config->GetModule("nickserv")->Get<bool>("forceemail", "yes"))
{
source.Reply(_("You cannot unset the e-mail on this network."));
+1 -1
View File
@@ -767,7 +767,7 @@ class OSSession : public Module
if (!e->expires || e->expires > Anope::CurTime)
continue;
BotInfo *OperServ = Config->GetClient("OperServ");
Log(OperServ, "expire/exception") << "Session exception for " << e->mask << "has expired.";
Log(OperServ, "expire/exception") << "Session exception for " << e->mask << " has expired.";
this->ss.DelException(e);
delete e;
}
+2 -2
View File
@@ -91,7 +91,7 @@ class CommandOSSVSJoin : public Command
Channel *c = Channel::Find(params[1]);
if (target == NULL)
source.Reply(NICK_X_NOT_IN_USE, params[0].c_str());
else if (target->IsProtected() || target->server == Me)
else if (source.GetUser() != target && (target->IsProtected() || target->server == Me))
source.Reply(ACCESS_DENIED);
else if (!IRCD->IsChannelValid(params[1]))
source.Reply(CHAN_X_INVALID, params[1].c_str());
@@ -135,7 +135,7 @@ class CommandOSSVSPart : public Command
Channel *c = Channel::Find(params[1]);
if (target == NULL)
source.Reply(NICK_X_NOT_IN_USE, params[0].c_str());
else if (target->IsProtected() || target->server == Me)
else if (source.GetUser() != target && (target->IsProtected() || target->server == Me))
source.Reply(ACCESS_DENIED);
else if (!c)
source.Reply(CHAN_X_NOT_IN_USE, params[1].c_str());
+3 -3
View File
@@ -221,7 +221,7 @@ class DBFlatFile : public Module, public Pipe
const Anope::string &db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database", "anope.db");
std::fstream fd(db_name.c_str(), std::ios_base::in);
std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary);
if (!fd.is_open())
{
Log(this) << "Unable to open " << db_name << " for reading!";
@@ -310,7 +310,7 @@ class DBFlatFile : public Module, public Pipe
if (Anope::IsFile(db_name))
rename(db_name.c_str(), (db_name + ".tmp").c_str());
std::fstream *fs = databases[s_type->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::out | std::ios_base::trunc);
std::fstream *fs = databases[s_type->GetOwner()] = new std::fstream(db_name.c_str(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
if (!fs->is_open())
Log(this) << "Unable to open " << db_name << " for writing";
@@ -382,7 +382,7 @@ class DBFlatFile : public Module, public Pipe
else
db_name = Anope::DataDir + "/" + Config->GetModule(this)->Get<const Anope::string>("database", "anope.db");
std::fstream fd(db_name.c_str(), std::ios_base::in);
std::fstream fd(db_name.c_str(), std::ios_base::in | std::ios_base::binary);
if (!fd.is_open())
{
Log(this) << "Unable to open " << db_name << " for reading!";
+43 -9
View File
@@ -16,6 +16,7 @@
#include "modules/os_news.h"
#include "modules/suspend.h"
#include "modules/os_forbid.h"
#include "modules/cs_entrymsg.h"
#define READ(x) \
if (true) \
@@ -141,7 +142,7 @@ enum
LANG_PL /* Polish */
};
static void process_mlock(ChannelInfo *ci, uint32_t lock, bool status)
static void process_mlock(ChannelInfo *ci, uint32_t lock, bool status, uint32_t *limit, Anope::string *key)
{
ModeLocks *ml = ci->Require<ModeLocks>("modelocks");
for (unsigned i = 0; i < (sizeof(mlock_infos) / sizeof(mlock_info)); ++i)
@@ -149,7 +150,14 @@ static void process_mlock(ChannelInfo *ci, uint32_t lock, bool status)
{
ChannelMode *cm = ModeManager::FindChannelModeByChar(mlock_infos[i].c);
if (cm && ml)
ml->SetMLock(cm, status);
{
if (limit && mlock_infos[i].c == 'l')
ml->SetMLock(cm, status, stringify(*limit));
else if (key && mlock_infos[i].c == 'k')
ml->SetMLock(cm, status, *key);
else
ml->SetMLock(cm, status);
}
}
}
@@ -926,9 +934,11 @@ static void LoadChannels()
READ(read_uint32(&tmpu32, f)); // mlock off
ci->Extend<uint32_t>("mlock_off", tmpu32);
READ(read_uint32(&tmpu32, f)); // mlock limit
READ(read_string(buffer, f));
READ(read_string(buffer, f));
READ(read_string(buffer, f));
ci->Extend<uint32_t>("mlock_limit", tmpu32);
READ(read_string(buffer, f)); // key
ci->Extend<Anope::string>("mlock_key", buffer);
READ(read_string(buffer, f)); // +f
READ(read_string(buffer, f)); // +L
READ(read_int16(&tmp16, f));
READ(read_int16(&ci->memos.memomax, f));
@@ -948,6 +958,21 @@ static void LoadChannels()
}
READ(read_string(buffer, f));
if (!buffer.empty())
{
EntryMessageList *eml = ci->Require<EntryMessageList>("entrymsg");
if (eml)
{
EntryMsg *e = eml->Create();
e->chan = ci->name;
e->creator = "Unknown";
e->message = buffer;
e->when = Anope::CurTime;
(*eml)->push_back(e);
}
}
READ(read_string(buffer, f));
ci->bi = BotInfo::Find(buffer);
@@ -1270,11 +1295,12 @@ static void LoadNews()
class DBOld : public Module
{
PrimitiveExtensibleItem<uint32_t> mlock_on, mlock_off;
PrimitiveExtensibleItem<uint32_t> mlock_on, mlock_off, mlock_limit;
PrimitiveExtensibleItem<Anope::string> mlock_key;
public:
DBOld(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, DATABASE | VENDOR),
mlock_on(this, "mlock_on"), mlock_off(this, "mlock_off")
mlock_on(this, "mlock_on"), mlock_off(this, "mlock_off"), mlock_limit(this, "mlock_limit"), mlock_key(this, "mlock_key")
{
@@ -1302,20 +1328,28 @@ class DBOld : public Module
for (registered_channel_map::iterator it = RegisteredChannelList->begin(), it_end = RegisteredChannelList->end(); it != it_end; ++it)
{
ChannelInfo *ci = it->second;
uint32_t *limit = mlock_limit.Get(ci);
Anope::string *key = mlock_key.Get(ci);
uint32_t *u = mlock_on.Get(ci);
if (u)
{
process_mlock(ci, *u, true);
process_mlock(ci, *u, true, limit, key);
mlock_on.Unset(ci);
}
u = mlock_off.Get(ci);
if (u)
{
process_mlock(ci, *u, false);
process_mlock(ci, *u, false, limit, key);
mlock_off.Unset(ci);
}
mlock_limit.Unset(ci);
mlock_key.Unset(ci);
if (ci->c)
ci->c->CheckModes();
}
}
};
+78 -26
View File
@@ -12,6 +12,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
int port;
Anope::string admin_binddn;
Anope::string admin_pass;
time_t timeout;
LDAP *con;
@@ -70,20 +71,26 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
}
public:
typedef std::map<int, LDAPInterface *> query_queue;
typedef std::map<LDAPQuery, std::pair<time_t, LDAPInterface *> > query_queue;
typedef std::vector<std::pair<LDAPInterface *, LDAPResult *> > result_queue;
query_queue queries;
result_queue results;
LDAPService(Module *o, const Anope::string &n, const Anope::string &s, int po, const Anope::string &b, const Anope::string &p) : LDAPProvider(o, n), server(s), port(po), admin_binddn(b), admin_pass(p), last_connect(0)
LDAPService(Module *o, const Anope::string &n, const Anope::string &s, int po, const Anope::string &b, const Anope::string &p, time_t t) : LDAPProvider(o, n), server(s), port(po), admin_binddn(b), admin_pass(p), timeout(t), last_connect(0)
{
int i = ldap_initialize(&this->con, this->server.c_str());
if (i != LDAP_SUCCESS)
throw LDAPException("Unable to connect to LDAP service " + this->name + ": " + ldap_err2string(i));
const int version = LDAP_VERSION3;
i = ldap_set_option(this->con, LDAP_OPT_PROTOCOL_VERSION, &version);
if (i != LDAP_OPT_SUCCESS)
throw LDAPException("Unable to set protocol version for " + this->name + ": " + ldap_err2string(i));
const struct timeval tv = { 0, 0 };
i = ldap_set_option(this->con, LDAP_OPT_NETWORK_TIMEOUT, &tv);
if (i != LDAP_OPT_SUCCESS)
throw LDAPException("Unable to set timeout for " + this->name + ": " + ldap_err2string(i));
}
~LDAPService()
@@ -92,15 +99,25 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
for (query_queue::iterator it = this->queries.begin(), it_end = this->queries.end(); it != it_end; ++it)
{
ldap_abandon_ext(this->con, it->first, NULL, NULL);
it->second->OnDelete();
LDAPQuery msgid = it->first;
LDAPInterface *i = it->second.second;
ldap_abandon_ext(this->con, msgid, NULL, NULL);
if (i)
i->OnDelete();
}
this->queries.clear();
for (result_queue::iterator it = this->results.begin(), it_end = this->results.end(); it != it_end; ++it)
{
it->second->error = "LDAP Interface is going away";
it->first->OnError(*it->second);
LDAPInterface *i = it->first;
LDAPResult *r = it->second;
r->error = "LDAP Interface is going away";
if (i)
i->OnError(*r);
delete r;
}
this->results.clear();
@@ -137,7 +154,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
if (i != NULL)
{
this->Lock();
this->queries[msgid] = i;
this->queries[msgid] = std::make_pair(Anope::CurTime, i);
this->Unlock();
}
this->Wakeup();
@@ -164,7 +181,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
}
this->Lock();
this->queries[msgid] = i;
this->queries[msgid] = std::make_pair(Anope::CurTime, i);
this->Unlock();
this->Wakeup();
@@ -192,7 +209,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
if (i != NULL)
{
this->Lock();
this->queries[msgid] = i;
this->queries[msgid] = std::make_pair(Anope::CurTime, i);
this->Unlock();
}
this->Wakeup();
@@ -219,7 +236,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
if (i != NULL)
{
this->Lock();
this->queries[msgid] = i;
this->queries[msgid] = std::make_pair(Anope::CurTime, i);
this->Unlock();
}
this->Wakeup();
@@ -248,7 +265,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
if (i != NULL)
{
this->Lock();
this->queries[msgid] = i;
this->queries[msgid] = std::make_pair(Anope::CurTime, i);
this->Unlock();
}
this->Wakeup();
@@ -256,6 +273,33 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
return msgid;
}
private:
void Timeout()
{
this->Lock();
for (query_queue::iterator it = this->queries.begin(), it_end = this->queries.end(); it != it_end;)
{
LDAPQuery msgid = it->first;
time_t created = it->second.first;
LDAPInterface *i = it->second.second;
++it;
if (Anope::CurTime > created + timeout)
{
LDAPResult *ldap_result = new LDAPResult();
ldap_result->id = msgid;
ldap_result->error = "Query timed out";
this->queries.erase(msgid);
this->results.push_back(std::make_pair(i, ldap_result));
me->Notify();
}
}
this->Unlock();
}
public:
void Run() anope_override
{
while (!this->GetExitState())
@@ -265,14 +309,15 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
this->Lock();
this->Wait();
this->Unlock();
if (this->GetExitState())
break;
continue;
}
else
this->Timeout();
struct timeval tv = { 1, 0 };
LDAPMessage *result;
int rtype = ldap_result(this->con, LDAP_RES_ANY, 1, &tv, &result);
if (rtype <= 0 || this->GetExitState())
if (rtype <= 0)
continue;
int cur_id = ldap_msgid(result);
@@ -286,7 +331,7 @@ class LDAPService : public LDAPProvider, public Thread, public Condition
ldap_msgfree(result);
continue;
}
LDAPInterface *i = it->second;
LDAPInterface *i = it->second.second;
this->queries.erase(it);
this->Unlock();
@@ -459,10 +504,11 @@ class ModuleLDAP : public Module, public Pipe
int port = ldap->Get<int>("port", "389");
const Anope::string &admin_binddn = ldap->Get<const Anope::string>("admin_binddn");
const Anope::string &admin_password = ldap->Get<const Anope::string>("admin_password");
time_t timeout = ldap->Get<time_t>("timeout", "5");
try
{
LDAPService *ss = new LDAPService(this, connname, server, port, admin_binddn, admin_password);
LDAPService *ss = new LDAPService(this, connname, server, port, admin_binddn, admin_password, timeout);
ss->Start();
this->LDAPServices.insert(std::make_pair(connname, ss));
@@ -484,11 +530,11 @@ class ModuleLDAP : public Module, public Pipe
s->Lock();
for (LDAPService::query_queue::iterator it2 = s->queries.begin(); it2 != s->queries.end();)
{
int msgid = it2->first;
LDAPInterface *i = it2->second;
LDAPQuery msgid = it2->first;
LDAPInterface *i = it2->second.second;
++it2;
if (i->owner == m)
if (i && i->owner == m)
{
i->OnDelete();
s->queries.erase(msgid);
@@ -499,7 +545,7 @@ class ModuleLDAP : public Module, public Pipe
LDAPInterface *li = s->results[i - 1].first;
LDAPResult *r = s->results[i - 1].second;
if (li->owner == m)
if (li && li->owner == m)
{
s->results.erase(s->results.begin() + i - 1);
delete r;
@@ -515,9 +561,9 @@ class ModuleLDAP : public Module, public Pipe
{
LDAPService *s = it->second;
LDAPService::result_queue results;
s->Lock();
LDAPService::result_queue results = s->results;
s->results.clear();
results.swap(s->results);
s->Unlock();
for (unsigned i = 0; i < results.size(); ++i)
@@ -525,10 +571,16 @@ class ModuleLDAP : public Module, public Pipe
LDAPInterface *li = results[i].first;
LDAPResult *r = results[i].second;
if (!r->error.empty())
li->OnError(*r);
else
li->OnResult(*r);
if (li != NULL)
{
if (!r->getError().empty())
{
Log(this) << "Error running LDAP query: " << r->getError();
li->OnError(*r);
}
else
li->OnResult(*r);
}
delete r;
}
+5 -5
View File
@@ -21,10 +21,10 @@ class DHAES : public Mechanism
}
public:
struct Session : SASL::Session
struct DHAESSession : SASL::Session
{
DH* dh;
Session(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
DHAESSession(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
{
if (!(dh = DH_new()))
return;
@@ -39,7 +39,7 @@ class DHAES : public Mechanism
}
}
~Session()
~DHAESSession()
{
if (dh)
DH_free(dh);
@@ -50,7 +50,7 @@ class DHAES : public Mechanism
const size_t keysize;
SASL::Session* CreateSession(const Anope::string &uid) anope_override
{
return new Session(this, uid, dh_params);
return new DHAESSession(this, uid, dh_params);
}
DHAES(Module *o) : Mechanism(o, "DH-AES"), keysize(256 / 8)
@@ -72,7 +72,7 @@ class DHAES : public Mechanism
void ProcessMessage(SASL::Session *session, const SASL::Message &m) anope_override
{
Session *sess = anope_dynamic_static_cast<Session *>(session);
DHAESSession *sess = anope_dynamic_static_cast<DHAESSession *>(session);
if (!sess->dh)
{
+5 -5
View File
@@ -21,10 +21,10 @@ class DHBS : public Mechanism
}
public:
struct Session : SASL::Session
struct DHBSSession : SASL::Session
{
DH* dh;
Session(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
DHBSSession(Mechanism *m, const Anope::string &u, DH* dh_params) : SASL::Session(m, u)
{
if (!(dh = DH_new()))
return;
@@ -39,7 +39,7 @@ class DHBS : public Mechanism
}
}
~Session()
~DHBSSession()
{
if (dh)
DH_free(dh);
@@ -50,7 +50,7 @@ class DHBS : public Mechanism
const size_t keysize;
SASL::Session* CreateSession(const Anope::string &uid) anope_override
{
return new Session(this, uid, dh_params);
return new DHBSSession(this, uid, dh_params);
}
DHBS(Module *o) : Mechanism(o, "DH-BLOWFISH"), keysize(256 / 8)
@@ -72,7 +72,7 @@ class DHBS : public Mechanism
void ProcessMessage(SASL::Session *session, const SASL::Message &m) anope_override
{
Session *sess = anope_dynamic_static_cast<Session *>(session);
DHBSSession *sess = anope_dynamic_static_cast<DHBSSession *>(session);
if (!sess->dh)
{
+15
View File
@@ -234,7 +234,11 @@ namespace GnuTLS
return ret;
}
#if (GNUTLS_VERSION_MAJOR < 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 12))
static int cert_callback(gnutls_session_t sess, const gnutls_datum_t* req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t* sign_algos, int sign_algos_length, gnutls_retr_st* st);
#else
static int cert_callback(gnutls_session_t sess, const gnutls_datum_t* req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t* sign_algos, int sign_algos_length, gnutls_retr2_st* st);
#endif
public:
X509CertList certs;
@@ -253,7 +257,11 @@ namespace GnuTLS
throw ConfigException("Unable to set cert/key pair");
}
#if (GNUTLS_VERSION_MAJOR < 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 12))
gnutls_certificate_client_set_retrieve_function(cred, cert_callback);
#else
gnutls_certificate_set_retrieve_function(cred, cert_callback);
#endif
}
~X509CertCredentials()
@@ -625,9 +633,16 @@ SSLSocketIO::SSLSocketIO() : sess(NULL), mycreds(me->cred)
mycreds->incrref();
}
#if (GNUTLS_VERSION_MAJOR < 2 || (GNUTLS_VERSION_MAJOR == 2 && GNUTLS_VERSION_MINOR < 12))
int GnuTLS::X509CertCredentials::cert_callback(gnutls_session_t sess, const gnutls_datum_t* req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t* sign_algos, int sign_algos_length, gnutls_retr_st* st)
{
st->type = GNUTLS_CRT_X509;
#else
int GnuTLS::X509CertCredentials::cert_callback(gnutls_session_t sess, const gnutls_datum_t* req_ca_rdn, int nreqs, const gnutls_pk_algorithm_t* sign_algos, int sign_algos_length, gnutls_retr2_st* st)
{
st->cert_type = GNUTLS_CRT_X509;
st->key_type = GNUTLS_PRIVKEY_X509;
#endif
st->ncerts = me->cred->certs.size();
st->cert.x509 = me->cred->certs.raw();
st->key.x509 = me->cred->key.get();
+5 -55
View File
@@ -87,7 +87,6 @@ void IRC2SQL::CheckTables()
query = "CREATE TABLE `" + prefix + "chan` ("
"`chanid` int(11) UNSIGNED NOT NULL AUTO_INCREMENT,"
"`channel` varchar(255) NOT NULL,"
"`currentusers` int(15) NOT NULL DEFAULT 0,"
"`topic` varchar(255) DEFAULT NULL,"
"`topicauthor` varchar(255) DEFAULT NULL,"
"`topictime` datetime DEFAULT NULL,"
@@ -230,47 +229,6 @@ void IRC2SQL::CheckTables()
query = "CREATE PROCEDURE " + prefix + "ServerQuit(sname_ varchar(255)) "
"BEGIN "
/* 1.
* loop through all channels and decrease the user count
* by the number of users that are on this channel AND
* on the splitting server
*
* we dont have to care about channels that get empty, there will be
* an extra OnChannelDelete event triggered from anope.
*/
"DECLARE no_more_rows BOOLEAN DEFAULT FALSE;"
"DECLARE channel_ varchar(255);"
"DECLARE ucount_ int;"
"DECLARE channel_cursor CURSOR FOR "
"SELECT c.channel "
"FROM `" + prefix + "chan` as c, `" + prefix + "ison` as i, "
"`" + prefix + "user` as u, `" + prefix + "server` as s "
"WHERE c.chanid = i.chanid "
"AND i.nickid = u.nickid "
"AND u.servid = s.id "
"AND s.name = sname_;"
"DECLARE CONTINUE HANDLER FOR NOT FOUND "
"SET no_more_rows = TRUE;"
"OPEN channel_cursor;"
"the_loop: LOOP "
"FETCH channel_cursor INTO channel_;"
"IF no_more_rows THEN "
"CLOSE channel_cursor;"
"LEAVE the_loop;"
"END IF;"
"SELECT COUNT(*) INTO ucount_ "
"FROM `" + prefix + "ison` AS i, `" + prefix + "chan` AS c,"
"`" + prefix + "user` AS u, `" + prefix + "server` AS s "
"WHERE i.nickid = u.nickid "
"AND u.servid = s.id "
"AND i.chanid = c.chanid "
"AND c.channel = channel_ "
"AND s.name = sname_; "
"UPDATE `" + prefix + "chan` "
"SET currentusers = currentusers - ucount_ "
"WHERE channel = channel_;"
"END LOOP;"
/* 2.
* remove all users on the splitting server from the ison table
*/
"DELETE i FROM `" + prefix + "ison` AS i "
@@ -280,7 +238,7 @@ void IRC2SQL::CheckTables()
"AND u.servid = s.id "
"AND s.name = sname_;"
/* 3.
/* 2.
* remove all users on the splitting server from the user table
*/
"DELETE u FROM `" + prefix + "user` AS u "
@@ -288,7 +246,7 @@ void IRC2SQL::CheckTables()
"WHERE s.id = u.servid "
"AND s.name = sname_;"
/* 4.
/* 3.
* on the splitting server, set usercount = 0, split_time = now(), online = 'N'
*/
"UPDATE `" + prefix + "server` SET currentusers = 0, split_time = now(), online = 'N' "
@@ -306,12 +264,6 @@ void IRC2SQL::CheckTables()
"UPDATE `" + prefix + "user` AS `u`, `" + prefix + "server` AS `s` "
"SET s.currentusers = s.currentusers - 1 "
"WHERE u.nick=nick_ AND u.servid = s.id; "
/* decrease the usercount on all channels where the user was on */
"UPDATE `" + prefix + "user` AS u, `" + prefix + "ison` AS i, "
"`" + prefix + "chan` AS c "
"SET c.currentusers = c.currentusers - 1 "
"WHERE u.nick=nick_ AND u.nickid = i.nickid "
"AND i.chanid = c.chanid; "
/* remove from all channels where the user was on */
"DELETE i FROM `" + prefix + "ison` AS i "
"INNER JOIN `" + prefix + "user` as u "
@@ -345,9 +297,9 @@ void IRC2SQL::CheckTables()
"SELECT u.nickid, c.chanid, modes_ "
"FROM " + prefix + "user AS u, " + prefix + "chan AS c "
"WHERE u.nick=nick_ AND c.channel=channel_;"
"UPDATE `" + prefix + "chan` SET currentusers=currentusers+1 "
"WHERE channel=channel_;"
"SELECT `currentusers` INTO cur FROM `" + prefix + "chan` WHERE channel=channel_;"
"SELECT count(i.chanid) INTO cur "
"FROM `" + prefix + "chan` AS c, " + prefix + "ison AS i "
"WHERE i.chanid = c.chanid AND c.channel=channel_;"
"SELECT `maxusers` INTO max FROM `" + prefix + "maxusers` WHERE name=channel_;"
"IF found_rows() AND cur <= max THEN "
"UPDATE `" + prefix + "maxusers` SET lastused=now() WHERE name=channel_;"
@@ -373,8 +325,6 @@ void IRC2SQL::CheckTables()
"AND u.nick = nick_ "
"AND i.chanid = c.chanid "
"AND c.channel = channel_;"
"UPDATE `" + prefix + "chan` SET currentusers=currentusers-1 "
"WHERE channel=channel_;"
"END";
this->RunQuery(query);
}
+5 -2
View File
@@ -162,8 +162,11 @@ class Fantasy : public Module
source.command = it->first;
source.permission = info.permission;
AccessGroup ag = c->ci->AccessFor(u);
bool has_fantasia = ag.HasPriv("FANTASIA") || source.HasPriv("chanserv/administration");
EventReturn MOD_RESULT;
if (c->ci->AccessFor(u).HasPriv("FANTASIA"))
if (has_fantasia)
{
FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params));
}
@@ -172,7 +175,7 @@ class Fantasy : public Module
FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params));
}
if (MOD_RESULT == EVENT_STOP || !c->ci->AccessFor(u).HasPriv("FANTASIA"))
if (MOD_RESULT == EVENT_STOP || !has_fantasia)
return;
if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission))
+2 -1
View File
@@ -93,13 +93,14 @@ class External : public Mechanism
}
NickCore *nc = certs->FindAccountFromCert(mysess->cert);
if (!nc)
if (!nc || nc->HasExt("NS_SUSPENDED"))
{
sasl->Fail(sess);
delete sess;
return;
}
Log(Config->GetClient("NickServ")) << "A user identified to account " << nc->display << " using SASL EXTERNAL";
sasl->Succeed(sess, nc);
delete sess;
}
+10 -2
View File
@@ -25,9 +25,9 @@ class NSMaxEmail : public Module
return false;
if (NSEmailMax == 1)
source.Reply(_("The given email address has reached its usage limit of 1 user."));
source.Reply(_("The email address \002%s\002 has reached its usage limit of 1 user."), email.c_str());
else
source.Reply(_("The given email address has reached its usage limit of %d users."), NSEmailMax);
source.Reply(_("The email address \002%s\002 has reached its usage limit of %d users."), email.c_str(), NSEmailMax);
return true;
}
@@ -57,6 +57,9 @@ class NSMaxEmail : public Module
EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector<Anope::string> &params) anope_override
{
if (source.IsOper())
return EVENT_CONTINUE;
if (command->name == "nickserv/register")
{
if (this->CheckLimitReached(source, params.size() > 1 ? params[1] : ""))
@@ -67,6 +70,11 @@ class NSMaxEmail : public Module
if (this->CheckLimitReached(source, params.size() > 0 ? params[0] : ""))
return EVENT_STOP;
}
else if (command->name == "nickserv/ungroup" && source.GetAccount())
{
if (this->CheckLimitReached(source, source.GetAccount()->email))
return EVENT_STOP;
}
return EVENT_CONTINUE;
}
+1 -1
View File
@@ -379,7 +379,7 @@ struct IRCDMessageNick : IRCDMessage
if (signon && signon == stamp)
na = NickAlias::Find(params[0]);
new User(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? *na->nc : NULL);
User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? *na->nc : NULL);
}
else
source.GetUser()->ChangeNick(params[0]);
+1 -1
View File
@@ -225,7 +225,7 @@ struct IRCDMessageEUID : IRCDMessage
if (params[9] != "*")
na = NickAlias::Find(params[9]);
new User(params[0], params[4], params[8], params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7], na ? *na->nc : NULL);
User::OnIntroduce(params[0], params[4], params[8], params[5], params[6], source.GetServer(), params[10], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime, params[3], params[7], na ? *na->nc : NULL);
}
};
+15 -2
View File
@@ -16,6 +16,19 @@ static Anope::string UplinkSID;
class HybridProto : public IRCDProto
{
BotInfo *FindIntroduced()
{
BotInfo *bi = Config->GetClient("OperServ");
if (bi && bi->introduced)
return bi;
for (botinfo_map::iterator it = BotListByNick->begin(), it_end = BotListByNick->end(); it != it_end; ++it)
if (it->second->introduced)
return it->second;
return NULL;
}
void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
{
IRCDProto::SendSVSKillInternal(source, user, buf);
@@ -54,7 +67,7 @@ class HybridProto : public IRCDProto
void SendSQLine(User *, const XLine *x) anope_override
{
UplinkSocket::Message(Config->GetClient("OperServ")) << "ENCAP * RESV " << (x->expires ? x->expires - Anope::CurTime : 0) << " " << x->mask << " 0 :" << x->reason;
UplinkSocket::Message(FindIntroduced()) << "ENCAP * RESV " << (x->expires ? x->expires - Anope::CurTime : 0) << " " << x->mask << " 0 :" << x->reason;
}
void SendSGLineDel(const XLine *x) anope_override
@@ -527,7 +540,7 @@ struct IRCDMessageUID : IRCDMessage
na = NickAlias::Find(params[8]);
/* Source is always the server */
new User(params[0], params[4], params[5], "",
User::OnIntroduce(params[0], params[4], params[5], "",
ip, source.GetServer(),
params[9], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0,
params[3], params[7], na ? *na->nc : NULL);
+3 -1
View File
@@ -1299,7 +1299,9 @@ struct IRCDMessageUID : IRCDMessage
++it;
}
new User(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0], na ? *na->nc : NULL);
User *u = User::OnIntroduce(params[2], params[5], params[3], params[4], params[6], source.GetServer(), params[params.size() - 1], ts, modes, params[0], na ? *na->nc : NULL);
if (u)
u->signon = convertTo<time_t>(params[7]);
}
};
+8 -2
View File
@@ -2,7 +2,7 @@
* ngIRCd Protocol module for Anope IRC Services
*
* (C) 2012 Anope Team <team@anope.org>
* (C) 2011-2012 Alexander Barton <alex@barton.de>
* (C) 2011-2012, 2014 Alexander Barton <alex@barton.de>
* (C) 2011 Anope Team <team@anope.org>
*
* Please read COPYING and README for further details.
@@ -15,6 +15,12 @@
class ngIRCdProto : public IRCDProto
{
void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override
{
IRCDProto::SendSVSKillInternal(source, user, buf);
user->KillInternal(source, buf);
}
public:
ngIRCdProto(Module *creator) : IRCDProto(creator, "ngIRCd")
{
@@ -437,7 +443,7 @@ struct IRCDMessageNick : IRCDMessage
else if (params.size() == 7)
{
// a new user is connecting to the network
new User(params[0], params[2], params[3], "", "", source.GetServer(), params[6], Anope::CurTime, params[5], "", NULL);
User::OnIntroduce(params[0], params[2], params[3], "", "", source.GetServer(), params[6], Anope::CurTime, params[5], "", NULL);
}
else
{
+3 -5
View File
@@ -86,14 +86,12 @@ class PlexusProto : public IRCDProto
if (!ident.empty())
UplinkSocket::Message(Me) << "ENCAP * CHGIDENT " << u->GetUID() << " " << ident;
UplinkSocket::Message(Me) << "ENCAP * CHGHOST " << u->GetUID() << " " << host;
u->SetMode(Config->GetClient("HostServ"), "CLOAK");
}
void SendVhostDel(User *u) anope_override
{
if (u->HasMode("CLOAK"))
u->RemoveMode(Config->GetClient("HostServ"), "CLOAK");
else
this->SendVhost(u, u->GetIdent(), u->chost);
u->RemoveMode(Config->GetClient("HostServ"), "CLOAK");
}
void SendConnect() anope_override
@@ -284,7 +282,7 @@ struct IRCDMessageUID : IRCDMessage
if (params[8] != "0" && !na)
na = NickAlias::Find(params[8]);
new User(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7], na ? *na->nc : NULL);
User::OnIntroduce(params[0], params[4], params[9], params[5], ip, source.GetServer(), params[10], ts, params[3], params[7], na ? *na->nc : NULL);
}
};
+1 -1
View File
@@ -197,7 +197,7 @@ struct IRCDMessageUID : IRCDMessage
void Run(MessageSource &source, const std::vector<Anope::string> &params) anope_override
{
/* Source is always the server */
new User(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], NULL);
User::OnIntroduce(params[0], params[4], params[5], "", params[6], source.GetServer(), params[8], params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, params[3], params[7], NULL);
}
};
+1 -1
View File
@@ -855,7 +855,7 @@ struct IRCDMessageNick : IRCDMessage
na = NickAlias::Find(params[6]);
}
new User(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7], "", na ? *na->nc : NULL);
User::OnIntroduce(params[0], params[3], params[4], vhost, ip, s, params[10], user_ts, params[7], "", na ? *na->nc : NULL);
}
else
source.GetUser()->ChangeNick(params[0]);
+2 -2
View File
@@ -136,7 +136,7 @@ class BotServCore : public Module
"channel, and provide a more convenient way to execute commands. Commands that\n"
"require a channel as a parameter will automatically have that parameter\n"
"given.\n"), source.service->nick.c_str());
const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!");
const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<const Anope::string>("fantasycharacter", "!");
if (!fantasycharacters.empty())
source.Reply(_(" \n"
"Fantasy commands may be prefixed with one of the following characters: %s\n"), fantasycharacters.c_str());
@@ -167,7 +167,7 @@ class BotServCore : public Module
source.Reply(_(" \n"
"Bot will join a channel whenever there is at least\n"
"\002%d\002 user(s) on it."), Config->GetModule(this)->Get<unsigned>("minusers"));
const Anope::string &fantasycharacters = Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!");
const Anope::string &fantasycharacters = Config->GetModule("fantasy")->Get<const Anope::string>("fantasycharacter", "!");
if (!fantasycharacters.empty())
source.Reply(_("Additionally, if fantasy is enabled fantasy commands\n"
"can be executed by prefixing the command name with\n"
+15 -1
View File
@@ -274,8 +274,11 @@ class ChanServCore : public Module, public ChanServService
"lists and settings for any channel."));
}
void OnCheckModes(Channel *c) anope_override
void OnCheckModes(Reference<Channel> &c) anope_override
{
if (!c)
return;
if (c->ci)
c->SetMode(c->ci->WhoSends(), "REGISTERED", "", false);
else
@@ -457,6 +460,17 @@ class ChanServCore : public Module, public ChanServService
if (!ci->HasExt("CS_NO_EXPIRE") && chanserv_expire && !Anope::NoExpire && ci->last_used != Anope::CurTime)
info[_("Expires")] = Anope::strftime(ci->last_used + chanserv_expire, source.GetAccount());
}
void OnSetCorrectModes(User *user, Channel *chan, AccessGroup &access, bool &give_modes, bool &take_modes) anope_override
{
if (always_lower)
// Since we always lower the TS, the other side will remove the modes if the channel ts lowers, so we don't
// have to worry about it
take_modes = false;
else if (ModeManager::FindChannelModeByName("REGISTERED"))
// Otherwise if the registered channel mode exists, we should remove modes if the channel is not +r
take_modes = !chan->HasMode("REGISTERED");
}
};
MODULE_INIT(ChanServCore)
+10 -3
View File
@@ -66,8 +66,8 @@ class NickServRelease : public User, public Timer
Anope::string nick;
public:
NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser"),
Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve(), NULL), Timer(delay), nick(na->nick)
NickServRelease(NickAlias *na, time_t delay) : User(na->nick, Config->GetModule("nickserv")->Get<const Anope::string>("enforceruser", "user"),
Config->GetModule("nickserv")->Get<const Anope::string>("enforcerhost", "services.localhost.net"), "", "", Me, "Services Enforcer", Anope::CurTime, "", Servers::TS6_UID_Retrieve(), NULL), Timer(delay), nick(na->nick)
{
/* Erase the current release timer and use the new one */
Anope::map<NickServRelease *>::iterator nit = NickServReleases.find(this->nick);
@@ -201,6 +201,10 @@ class NickServCore : public Module, public NickServService
NickAlias *na = NickAlias::Find(u->nick);
if (na && *na->nc == u->Account() && !Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !na->nc->HasExt("UNCONFIRMED"))
u->SetMode(NickServ, "REGISTERED");
const Anope::string &modesonid = Config->GetModule(this)->Get<Anope::string>("modesonid");
if (!modesonid.empty())
u->SetModes(NickServ, "%s", modesonid.c_str());
}
void Collide(User *u, NickAlias *na) anope_override
@@ -210,6 +214,7 @@ class NickServCore : public Module, public NickServService
if (IRCD->CanSVSNick)
{
unsigned nicklen = Config->GetBlock("networkinfo")->Get<unsigned>("nicklen");
const Anope::string &guestprefix = Config->GetModule("nickserv")->Get<const Anope::string>("guestnickprefix", "Guest");
Anope::string guestnick;
@@ -218,6 +223,8 @@ class NickServCore : public Module, public NickServService
do
{
guestnick = guestprefix + stringify(static_cast<uint16_t>(rand()));
if (guestnick.length() > nicklen)
guestnick = guestnick.substr(0, nicklen);
}
while (User::Find(guestnick) && i++ < 10);
@@ -363,7 +370,7 @@ class NickServCore : public Module, public NickServService
const NickAlias *na = NickAlias::Find(u->nick);
const Anope::string &unregistered_notice = Config->GetModule(this)->Get<const Anope::string>("unregistered_notice");
if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na)
if (!Config->GetModule("nickserv")->Get<bool>("nonicknameownership") && !unregistered_notice.empty() && !na && !u->Account())
u->SendMessage(NickServ, unregistered_notice);
else if (na && !u->IsIdentified(true))
this->Validate(u);
+18 -1
View File
@@ -108,14 +108,31 @@ Serializable* BotInfo::Unserialize(Serializable *obj, Serialize::Data &data)
void BotInfo::GenerateUID()
{
if (this->introduced)
throw CoreException("Changing bot UID when it is introduced?");
if (!this->uid.empty())
throw CoreException("Bot already has a uid?");
{
BotListByUID->erase(this->uid);
UserListByUID.erase(this->uid);
}
this->uid = Servers::TS6_UID_Retrieve();
(*BotListByUID)[this->uid] = this;
UserListByUID[this->uid] = this;
}
void BotInfo::OnKill()
{
this->introduced = false;
this->GenerateUID();
IRCD->SendClientIntroduction(this);
this->introduced = true;
for (User::ChanUserList::const_iterator cit = this->chans.begin(), cit_end = this->chans.end(); cit != cit_end; ++cit)
IRCD->SendJoin(this, cit->second->chan, &cit->second->status);
}
void BotInfo::SetNewNick(const Anope::string &newnick)
{
UserListByNick.erase(this->nick);
+35 -20
View File
@@ -78,8 +78,12 @@ void Channel::Reset()
/* reset modes for my clients */
if (uc->user->server == Me)
{
for (size_t i = 0; i < f.Modes().length(); ++i)
this->SetMode(NULL, ModeManager::FindChannelModeByChar(f.Modes()[i]), uc->user->GetUID(), false);
/* Modes might not exist yet, so be sure the status is really reset */
uc->status = f;
}
}
for (ChanUserList::const_iterator it = this->users.begin(), it_end = this->users.end(); it != it_end; ++it)
@@ -111,7 +115,8 @@ void Channel::CheckModes()
return;
}
FOREACH_MOD(OnCheckModes, (this));
Reference<Channel> ref = this;
FOREACH_MOD(OnCheckModes, (ref));
}
bool Channel::CheckDelete()
@@ -371,6 +376,15 @@ void Channel::RemoveModeInternal(MessageSource &setter, ChannelMode *cm, const A
FOREACH_RESULT(OnChannelModeUnset, MOD_RESULT, (this, setter, cm, param));
if (cm->name == "PERM")
{
if (this->CheckDelete())
{
delete this;
return;
}
}
/* Check for mlock */
if (!enforce_mlock || MOD_RESULT == EVENT_STOP)
return;
@@ -505,9 +519,11 @@ void Channel::SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...)
vsnprintf(buf, BUFSIZE - 1, cmodes, args);
va_end(args);
Reference<Channel> this_reference(this);
spacesepstream sep(buf);
sep.GetToken(modebuf);
for (unsigned i = 0, end = modebuf.length(); i < end; ++i)
for (unsigned i = 0, end = modebuf.length(); this_reference && i < end; ++i)
{
ChannelMode *cm;
@@ -562,17 +578,6 @@ void Channel::SetModes(BotInfo *bi, bool enforce_mlock, const char *cmodes, ...)
void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts, bool enforce_mlock)
{
if (source.GetServer() && source.GetServer()->IsSynced())
{
if (Anope::CurTime != this->server_modetime)
{
this->server_modecount = 0;
this->server_modetime = Anope::CurTime;
}
++this->server_modecount;
}
if (!ts)
;
else if (ts > this->creation_time)
@@ -599,6 +604,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
Anope::string modestring;
Anope::string paramstring;
int add = -1;
bool changed = false;
for (unsigned int i = 0, end = m.length(); i < end && this_reference; ++i)
{
ChannelMode *cm;
@@ -627,6 +633,8 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
if (cm->type == MODE_REGULAR)
{
/* something changed if we are adding a mode we dont have, or removing one we have */
changed |= !!add != this->HasMode(cm->name);
if (add)
this->SetModeInternal(source, cm, "", false);
else
@@ -652,6 +660,7 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
else
paramstring += " " + token;
changed |= !!add != this->HasMode(cm->name, token);
/* CheckModes below doesn't check secureops (+ the module event) */
if (add)
this->SetModeInternal(source, cm, token, enforce_mlock);
@@ -665,6 +674,17 @@ void Channel::SetModesInternal(MessageSource &source, const Anope::string &mode,
if (!this_reference)
return;
if (changed && source.GetServer() && source.GetServer()->IsSynced())
{
if (Anope::CurTime != this->server_modetime)
{
this->server_modecount = 0;
this->server_modetime = Anope::CurTime;
}
++this->server_modecount;
}
if (setter)
Log(setter, this, "mode") << modestring << paramstring;
else
@@ -788,14 +808,9 @@ void Channel::SetCorrectModes(User *user, bool give_modes)
Log(LOG_DEBUG) << "Setting correct user modes for " << user->nick << " on " << this->name << " (" << (give_modes ? "" : "not ") << "giving modes)";
AccessGroup u_access = ci->AccessFor(user);
ChannelMode *registered = ModeManager::FindChannelModeByName("REGISTERED");
/* If this channel has secureops, or the registered channel mode exists and the channel does not have +r set (aka the channel
* was created just now or while we were off), or the registered channel mode does not exist and channel is syncing (aka just
* created *to us*) and the user's server is synced (aka this isn't us doing our initial uplink - without this we would be deopping all
* users with no access on a non-secureops channel on startup), and the user's server isn't ulined, then set negative modes.
*/
bool take_modes = (registered && !this->HasMode("REGISTERED")) || (!registered && this->syncing && user->server->IsSynced());
/* Initially only take modes if the channel is being created by a non netmerge */
bool take_modes = this->syncing && user->server->IsSynced();
FOREACH_MOD(OnSetCorrectModes, (user, this, u_access, give_modes, take_modes));
+3 -39
View File
@@ -18,13 +18,6 @@
#include "channels.h"
#include "hashcomp.h"
#ifndef _WIN32
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#endif
using namespace Configuration;
File ServicesConf("services.conf", false); // Services configuration file name
@@ -533,31 +526,6 @@ Conf::Conf() : Block("")
if (!options->Get<unsigned>("seed"))
Log() << "Configuration option options:seed should be set. It's for YOUR safety! Remember that!";
#ifndef _WIN32
if (!options->Get<const Anope::string>("user").empty())
{
errno = 0;
struct passwd *u = getpwnam(options->Get<const Anope::string>("user").c_str());
if (u == NULL)
Log() << "Unable to setuid to " << options->Get<const Anope::string>("user") << ": " << Anope::LastError();
else if (setuid(u->pw_uid) == -1)
Log() << "Unable to setuid to " << options->Get<const Anope::string>("user") << ": " << Anope::LastError();
else
Log() << "Successfully set user to " << options->Get<const Anope::string>("user");
}
if (!options->Get<const Anope::string>("group").empty())
{
errno = 0;
struct group *g = getgrnam(options->Get<const Anope::string>("group").c_str());
if (g == NULL)
Log() << "Unable to setgid to " << options->Get<const Anope::string>("group") << ": " << Anope::LastError();
else if (setuid(g->gr_gid) == -1)
Log() << "Unable to setgid to " << options->Get<const Anope::string>("group") << ": " << Anope::LastError();
else
Log() << "Successfully set group to " << options->Get<const Anope::string>("group");
}
#endif
if (Config)
{
/* Apply module chnages */
@@ -754,8 +722,10 @@ void Conf::LoadConf(File &file)
{
in_comment = false;
++c;
// We might be at an eol, so continue on and process it
}
continue;
else
continue;
}
else if (ch == '#' || (ch == '/' && c + 1 < len && line[c + 1] == '/'))
c = len - 1; // Line comment, ignore the rest of the line (much like this one!)
@@ -876,12 +846,6 @@ void Conf::LoadConf(File &file)
if (b)
Log(LOG_DEBUG) << "ln " << linenumber << " EOL: s='" << b->name << "' '" << itemname << "' set to '" << wordbuffer << "'";
if (itemname.empty())
{
file.Close();
throw ConfigException("Item without a name: " + file.GetName() + ":" + stringify(linenumber));
}
/* Check defines */
for (int i = 0; i < this->CountBlock("define"); ++i)
{
+65 -3
View File
@@ -23,6 +23,11 @@
#ifndef _WIN32
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
#endif
Anope::string Anope::ConfigDir = "conf", Anope::DataDir = "data", Anope::ModuleDir = "lib", Anope::LocaleDir = "locale", Anope::LogDir = "logs";
@@ -219,6 +224,61 @@ static void write_pidfile()
throw CoreException("Can not write to PID file " + Config->GetBlock("serverinfo")->Get<const Anope::string>("pid"));
}
static void setuidgid()
{
#ifndef _WIN32
Configuration::Block *options = Config->GetBlock("options");
uid_t uid = -1;
gid_t gid = -1;
if (!options->Get<const Anope::string>("user").empty())
{
errno = 0;
struct passwd *u = getpwnam(options->Get<const Anope::string>("user").c_str());
if (u == NULL)
Log() << "Unable to setuid to " << options->Get<const Anope::string>("user") << ": " << Anope::LastError();
else
uid = u->pw_uid;
}
if (!options->Get<const Anope::string>("group").empty())
{
errno = 0;
struct group *g = getgrnam(options->Get<const Anope::string>("group").c_str());
if (g == NULL)
Log() << "Unable to setgid to " << options->Get<const Anope::string>("group") << ": " << Anope::LastError();
else
gid = g->gr_gid;
}
for (unsigned i = 0; i < Config->LogInfos.size(); ++i)
{
LogInfo& li = Config->LogInfos[i];
for (unsigned j = 0; j < li.logfiles.size(); ++j)
{
LogFile* lf = li.logfiles[j];
chown(lf->filename.c_str(), uid, gid);
}
}
if (static_cast<int>(gid) != -1)
{
if (setgid(gid) == -1)
Log() << "Unable to setgid to " << options->Get<const Anope::string>("group") << ": " << Anope::LastError();
else
Log() << "Successfully set group to " << options->Get<const Anope::string>("group");
}
if (static_cast<int>(uid) != -1)
{
if (setuid(uid) == -1)
Log() << "Unable to setuid to " << options->Get<const Anope::string>("user") << ": " << Anope::LastError();
else
Log() << "Successfully set user to " << options->Get<const Anope::string>("user");
}
#endif
}
void Anope::Init(int ac, char **av)
{
/* Set file creation mask and group ID. */
@@ -425,9 +485,6 @@ void Anope::Init(int ac, char **av)
throw CoreException("Configuration file failed to validate");
}
/* Write our PID to the PID file. */
write_pidfile();
/* Create me */
Configuration::Block *block = Config->GetBlock("serverinfo");
Me = new Server(NULL, block->Get<const Anope::string>("name"), 0, block->Get<const Anope::string>("description"), block->Get<const Anope::string>("id"));
@@ -454,10 +511,15 @@ void Anope::Init(int ac, char **av)
for (int i = 0; i < Config->CountBlock("module"); ++i)
ModuleManager::LoadModule(Config->GetBlock("module", i)->Get<const Anope::string>("name"), NULL);
setuidgid();
Module *protocol = ModuleManager::FindFirstOf(PROTOCOL);
if (protocol == NULL)
throw CoreException("You must load a protocol module!");
/* Write our PID to the PID file. */
write_pidfile();
Log() << "Using IRCd protocol " << protocol->name;
/* Auto assign sid if applicable */
+1 -6
View File
@@ -199,12 +199,7 @@ void Kill::Run(MessageSource &source, const std::vector<Anope::string> &params)
}
last_time = Anope::CurTime;
bi->introduced = false;
IRCD->SendClientIntroduction(bi);
bi->introduced = true;
for (User::ChanUserList::const_iterator cit = bi->chans.begin(), cit_end = bi->chans.end(); cit != cit_end; ++cit)
IRCD->SendJoin(bi, cit->second->chan, &cit->second->status);
bi->OnKill();
}
else
u->KillInternal(source.GetSource(), params[1]);
+5
View File
@@ -45,6 +45,11 @@ const Anope::string &IRCDProto::GetProtocolName()
return this->proto_name;
}
void IRCDProto::SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason)
{
UplinkSocket::Message(source) << "KILL " << target << " :" << reason;
}
void IRCDProto::SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf)
{
UplinkSocket::Message(source) << "KILL " << user->GetUID() << " :" << buf;
+2
View File
@@ -127,6 +127,8 @@ Server::Server(Server *up, const Anope::string &sname, unsigned shops, const Ano
if (!c->topic.empty() && !c->topic_setter.empty())
IRCD->SendTopic(c->ci->WhoSends(), c);
c->syncing = true;
}
}
}
+2 -1
View File
@@ -138,7 +138,8 @@ void UplinkSocket::OnConnect()
void UplinkSocket::OnError(const Anope::string &error)
{
Log(LOG_TERMINAL) << "Unable to connect to uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << ")" << (!error.empty() ? (": " + error) : "");
Anope::string what = !this->flags[SF_CONNECTED] ? "Unable to connect to" : "Lost connection from";
Log(LOG_TERMINAL) << what << " uplink #" << (Anope::CurrentUplink + 1) << " (" << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port << ")" << (!error.empty() ? (": " + error) : "");
}
UplinkSocket::Message::Message() : source(Me)
+62 -3
View File
@@ -33,7 +33,7 @@ time_t MaxUserTime = 0;
std::list<User *> User::quitting_users;
User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid, NickCore *account)
User::User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *account)
{
if (snick.empty() || sident.empty() || shost.empty())
throw CoreException("Bad args passed to User::User");
@@ -52,7 +52,7 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
this->ip = sip;
this->server = sserver;
this->realname = srealname;
this->timestamp = this->signon = ssignon;
this->timestamp = this->signon = ts;
this->SetModesInternal(sserver, "%s", smodes.c_str());
this->uid = suid;
this->super_admin = false;
@@ -88,6 +88,56 @@ User::User(const Anope::string &snick, const Anope::string &sident, const Anope:
FOREACH_MOD(OnUserConnect, (this, exempt));
}
static void CollideKill(User *target, const Anope::string &reason)
{
if (target->server != Me)
target->Kill(Me, reason);
else
{
// Be sure my user is really dead
IRCD->SendQuit(target, "%s", reason.c_str());
// Reintroduce my client
if (BotInfo *bi = dynamic_cast<BotInfo *>(target))
bi->OnKill();
else
target->Quit(reason);
}
}
static void Collide(User *u, const Anope::string &id, const Anope::string &type)
{
// Kill incoming user
IRCD->SendKill(Me, id, type);
// Quit colliding user
CollideKill(u, type);
}
User* User::OnIntroduce(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ts, const Anope::string &smodes, const Anope::string &suid, NickCore *nc)
{
// How IRCds handle collisions varies a lot, for safety well just always kill both sides
// With properly set qlines, this can almost never happen anyway
User *u = User::Find(snick);
if (u)
{
Collide(u, !suid.empty() ? suid : snick, "Nick collision");
return NULL;
}
if (!suid.empty())
{
u = User::Find(suid);
if (u)
{
Collide(u, suid, "ID collision");
return NULL;
}
}
return new User(snick, sident, shost, svhost, sip, sserver, srealname, ts, smodes, suid, nc);
}
void User::ChangeNick(const Anope::string &newnick, time_t ts)
{
/* Sanity check to make sure we don't segfault */
@@ -109,8 +159,17 @@ void User::ChangeNick(const Anope::string &newnick, time_t ts)
old_na->last_seen = Anope::CurTime;
UserListByNick.erase(this->nick);
this->nick = newnick;
UserListByNick[this->nick] = this;
User* &other = UserListByNick[this->nick];
if (other)
{
CollideKill(this, "Nick collision");
CollideKill(other, "Nick collision");
return;
}
other = this;
on_access = false;
NickAlias *na = NickAlias::Find(this->nick);
+1 -1
View File
@@ -3,5 +3,5 @@
VERSION_MAJOR="2"
VERSION_MINOR="0"
VERSION_PATCH="0"
VERSION_EXTRA="-rc4"
VERSION_EXTRA=""