mirror of
https://github.com/anope/anope.git
synced 2026-06-22 00:36:36 +02:00
Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4ccc478830 | |||
| 100ecbb9be | |||
| cdf636e696 | |||
| 45878bf182 | |||
| f1bec3999d | |||
| a259244297 | |||
| c1da009de3 | |||
| 4f412bc213 | |||
| 1882916dc4 | |||
| f436ce9912 | |||
| ef9729fb02 | |||
| 296a75f2a9 | |||
| bce7237d9f | |||
| 85834e19dc | |||
| ca6b3723a9 | |||
| 23b1086072 | |||
| 860deb14ce | |||
| 62885fa462 | |||
| 3fef01e35b | |||
| b0597e35ec | |||
| 8d1ad6fbe5 | |||
| 750569201a | |||
| 1a1a781b72 | |||
| 4b5ce8a972 | |||
| 98cfdd26c4 | |||
| 051a42b547 | |||
| 220e278213 | |||
| 547fe0da1a | |||
| 09bec79b47 | |||
| 55a5affcb8 | |||
| a8b4297023 | |||
| 5969362425 | |||
| 3ceae33b16 | |||
| 5de4c1fc97 | |||
| fd109048dd | |||
| a0747516ce | |||
| 605e1f2a03 | |||
| dc23c58869 | |||
| b7e646ec83 | |||
| 4d54358745 | |||
| ed0882ec04 | |||
| 526c4e4659 | |||
| b70f72bf2b | |||
| 2ad4c1906e | |||
| 049760cc7e | |||
| e2ecec31b5 | |||
| fee016bb84 | |||
| d24fb03917 | |||
| 5adc8bfefc | |||
| abcf0cde5a | |||
| 8f3bd314ed | |||
| e2d456d4ce | |||
| 96202ae545 | |||
| 2b0229d4e2 | |||
| beaa3196b3 |
+2
-14
@@ -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
|
||||
|
||||
@@ -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"; }
|
||||
|
||||
/*
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
-------------------
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
+332
-323
File diff suppressed because it is too large
Load Diff
+334
-334
File diff suppressed because it is too large
Load Diff
+631
-707
File diff suppressed because it is too large
Load Diff
+331
-321
File diff suppressed because it is too large
Load Diff
+330
-324
File diff suppressed because it is too large
Load Diff
+337
-327
File diff suppressed because it is too large
Load Diff
+330
-326
File diff suppressed because it is too large
Load Diff
+330
-324
File diff suppressed because it is too large
Load Diff
+330
-324
File diff suppressed because it is too large
Load Diff
+331
-324
File diff suppressed because it is too large
Load Diff
+330
-324
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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]"));
|
||||
}
|
||||
|
||||
@@ -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> ¶ms) 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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."));
|
||||
|
||||
@@ -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."));
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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!";
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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> ¶ms) 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;
|
||||
}
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ struct IRCDMessageUID : IRCDMessage
|
||||
void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) 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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -199,12 +199,7 @@ void Kill::Run(MessageSource &source, const std::vector<Anope::string> ¶ms)
|
||||
}
|
||||
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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -3,5 +3,5 @@
|
||||
VERSION_MAJOR="2"
|
||||
VERSION_MINOR="0"
|
||||
VERSION_PATCH="0"
|
||||
VERSION_EXTRA="-rc4"
|
||||
VERSION_EXTRA=""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user