From f64cb901efe2f303413816b725520dfd4caee7bf Mon Sep 17 00:00:00 2001 From: Ian Chard Date: Wed, 24 Jun 2015 15:37:56 +0100 Subject: [PATCH 1/5] Add channel mode N (normal user can't change nick while on channel) --- src/ngircd/irc-login.c | 15 +++++++++++++++ src/ngircd/irc-mode.c | 1 + src/ngircd/messages.h | 1 + 3 files changed, 17 insertions(+) diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 98ac0e7f..f3226011 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -172,6 +172,7 @@ GLOBAL bool IRC_NICK( CLIENT *Client, REQUEST *Req ) { CLIENT *intr_c, *target, *c; + CHANNEL *chan; char *nick, *user, *hostname, *modes, *info; int token, hops; @@ -259,6 +260,20 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) Client_SetType( Client, CLIENT_GOTNICK ); } else { /* Nickname change */ + + /* Check that the user isn't on any channels set +N */ + chan = Channel_First(); + while (chan) { + if(Channel_IsMemberOf(chan, Client) && + Channel_HasMode(chan, 'N') && + !Client_HasMode(Client, 'o')) + return IRC_WriteErrClient(Client, + ERR_UNAVAILRESOURCE_MSG, + Client_ID(Client), + Channel_Name(chan)); + chan = Channel_Next(chan); + } + Change_Nick(Client, target, Req->argv[0], Client_Type(Client) == CLIENT_USER ? true : false); IRC_SetPenalty(target, 2); diff --git a/src/ngircd/irc-mode.c b/src/ngircd/irc-mode.c index 2f922506..99255df1 100644 --- a/src/ngircd/irc-mode.c +++ b/src/ngircd/irc-mode.c @@ -580,6 +580,7 @@ Channel_Mode(CLIENT *Client, REQUEST *Req, CLIENT *Origin, CHANNEL *Channel) case 'M': /* Only identified nicks can write */ case 'm': /* Moderated */ case 'n': /* Only members can write */ + case 'N': /* Can't change nick while on this channel */ case 'Q': /* No kicks */ case 't': /* Topic locked */ if(is_oper || is_machine || is_owner || diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h index 8a7215b4..15dbe8cf 100644 --- a/src/ngircd/messages.h +++ b/src/ngircd/messages.h @@ -122,6 +122,7 @@ #define ERR_NICKNAMETOOLONG_MSG "432 %s %s :Nickname too long, max. %u characters" #define ERR_FORBIDDENNICKNAME_MSG "432 %s %s :Nickname is forbidden/blocked" #define ERR_NICKNAMEINUSE_MSG "433 %s %s :Nickname already in use" +#define ERR_UNAVAILRESOURCE_MSG "437 %s :Cannot change nickname while on %s(+N)" #define ERR_USERNOTINCHANNEL_MSG "441 %s %s %s :They aren't on that channel" #define ERR_NOTONCHANNEL_MSG "442 %s %s :You are not on that channel" #define ERR_USERONCHANNEL_MSG "443 %s %s %s :is already on channel" From 27934afd7e0acd3562fe899982560207c0b3f02a Mon Sep 17 00:00:00 2001 From: Ian Chard Date: Wed, 24 Jun 2015 15:41:31 +0100 Subject: [PATCH 2/5] Add documentation for channel mode N --- doc/Modes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/Modes.txt b/doc/Modes.txt index 07f16eb0..2230f36e 100644 --- a/doc/Modes.txt +++ b/doc/Modes.txt @@ -56,6 +56,7 @@ users to lists (e.g. "invite list", "ban list"), others have parameters m 0.3.0 Channel is moderated, only "voiced" users can send messages. M 20 Only registered users (and IRC Ops) can send messages. n 0.3.0 Channel doesn't allow messages of users not being members. + N ?? Users can't change their nickname while on this channel. O 18 Only IRC operators are allowed to join this channel. P 0.5.0 Channel is "persistent". Q 20 Nobody can be kicked from the channel. From adfe5affedac5dcf3f66a1a8363429ba1a13ebeb Mon Sep 17 00:00:00 2001 From: Ian Chard Date: Wed, 24 Jun 2015 15:51:37 +0100 Subject: [PATCH 3/5] Don't use a standard message number --- src/ngircd/irc-login.c | 2 +- src/ngircd/messages.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index f3226011..79c0dcd4 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -268,7 +268,7 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) Channel_HasMode(chan, 'N') && !Client_HasMode(Client, 'o')) return IRC_WriteErrClient(Client, - ERR_UNAVAILRESOURCE_MSG, + ERR_NONICKCHANGE_MSG, Client_ID(Client), Channel_Name(chan)); chan = Channel_Next(chan); diff --git a/src/ngircd/messages.h b/src/ngircd/messages.h index 15dbe8cf..4f1632b0 100644 --- a/src/ngircd/messages.h +++ b/src/ngircd/messages.h @@ -122,12 +122,12 @@ #define ERR_NICKNAMETOOLONG_MSG "432 %s %s :Nickname too long, max. %u characters" #define ERR_FORBIDDENNICKNAME_MSG "432 %s %s :Nickname is forbidden/blocked" #define ERR_NICKNAMEINUSE_MSG "433 %s %s :Nickname already in use" -#define ERR_UNAVAILRESOURCE_MSG "437 %s :Cannot change nickname while on %s(+N)" #define ERR_USERNOTINCHANNEL_MSG "441 %s %s %s :They aren't on that channel" #define ERR_NOTONCHANNEL_MSG "442 %s %s :You are not on that channel" #define ERR_USERONCHANNEL_MSG "443 %s %s %s :is already on channel" #define ERR_SUMMONDISABLED_MSG "445 %s :SUMMON has been disabled" #define ERR_USERSDISABLED_MSG "446 %s :USERS has been disabled" +#define ERR_NONICKCHANGE_MSG "447 %s :Cannot change nickname while on %s(+N)" #define ERR_NOTREGISTERED_MSG "451 %s :Connection not registered" #define ERR_NOTREGISTEREDSERVER_MSG "451 %s :Connection not registered as server link" #define ERR_NEEDMOREPARAMS_MSG "461 %s %s :Syntax error" From 7ff16e81163b3bee43ce053cb86fb2df2a023d53 Mon Sep 17 00:00:00 2001 From: Ian Chard Date: Wed, 24 Jun 2015 20:28:27 +0100 Subject: [PATCH 4/5] Don't bother looking for +N channels for an op --- src/ngircd/irc-login.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 79c0dcd4..10885f28 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -262,16 +262,17 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) /* Nickname change */ /* Check that the user isn't on any channels set +N */ - chan = Channel_First(); - while (chan) { - if(Channel_IsMemberOf(chan, Client) && - Channel_HasMode(chan, 'N') && - !Client_HasMode(Client, 'o')) - return IRC_WriteErrClient(Client, - ERR_NONICKCHANGE_MSG, - Client_ID(Client), - Channel_Name(chan)); - chan = Channel_Next(chan); + if(!Client_HasMode(Client, 'o')) { + chan = Channel_First(); + while (chan) { + if(Channel_IsMemberOf(chan, Client) && + Channel_HasMode(chan, 'N')) + return IRC_WriteErrClient(Client, + ERR_NONICKCHANGE_MSG, + Client_ID(Client), + Channel_Name(chan)); + chan = Channel_Next(chan); + } } Change_Nick(Client, target, Req->argv[0], From 599626d570f5bd5284a7a30fb8c3ca8dc3636371 Mon Sep 17 00:00:00 2001 From: Ian Chard Date: Fri, 26 Jun 2015 10:36:57 +0100 Subject: [PATCH 5/5] Only enforce channel mode N on users (not servers or services) --- src/ngircd/irc-login.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ngircd/irc-login.c b/src/ngircd/irc-login.c index 10885f28..35026e55 100644 --- a/src/ngircd/irc-login.c +++ b/src/ngircd/irc-login.c @@ -262,7 +262,8 @@ IRC_NICK( CLIENT *Client, REQUEST *Req ) /* Nickname change */ /* Check that the user isn't on any channels set +N */ - if(!Client_HasMode(Client, 'o')) { + if(Client_Type(Client) == CLIENT_USER && + !Client_HasMode(Client, 'o')) { chan = Channel_First(); while (chan) { if(Channel_IsMemberOf(chan, Client) &&