diff --git a/docs/MANUAL.md b/docs/MANUAL.md index fce43db5..07d7c23b 100644 --- a/docs/MANUAL.md +++ b/docs/MANUAL.md @@ -35,6 +35,7 @@ _Copyright © Daniel Oaks , Shivaram Lingamneni ")) return false } @@ -906,24 +906,30 @@ func dlineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res var killClient bool if andKill { - var clientsToKill []*Client + var sessionsToKill []*Session var killedClientNicks []string for _, mcl := range server.clients.AllClients() { - if hostNet.Contains(mcl.IP()) { - clientsToKill = append(clientsToKill, mcl) - killedClientNicks = append(killedClientNicks, mcl.nick) + nickKilled := false + for _, session := range mcl.Sessions() { + if hostNet.Contains(session.IP()) { + sessionsToKill = append(sessionsToKill, session) + if !nickKilled { + killedClientNicks = append(killedClientNicks, mcl.Nick()) + nickKilled = true + } + } } } - for _, mcl := range clientsToKill { - mcl.SetExitedSnomaskSent() - mcl.Quit(fmt.Sprintf(mcl.t("You have been banned from this server (%s)"), reason), nil) - if mcl == client { + for _, session := range sessionsToKill { + mcl := session.client + mcl.Quit(fmt.Sprintf(mcl.t("You have been banned from this server (%s)"), reason), session) + if session == rb.session { killClient = true } else { // if mcl == client, we kill them below - mcl.destroy(nil) + mcl.destroy(session) } } @@ -1296,14 +1302,15 @@ func killHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Resp target := server.clients.Get(nickname) if target == nil { - rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.nick, utils.SafeErrorParam(nickname), client.t("No such nick")) + rb.Add(nil, client.server.name, ERR_NOSUCHNICK, client.Nick(), utils.SafeErrorParam(nickname), client.t("No such nick")) return false + } else if target.AlwaysOn() { + rb.Add(nil, client.server.name, ERR_UNKNOWNERROR, client.Nick(), "KILL", fmt.Sprintf(client.t("Client %s is always-on and cannot be fully removed by /KILL; consider /NS SUSPEND instead"), target.Nick())) } quitMsg := fmt.Sprintf("Killed (%s (%s))", client.nick, comment) server.snomasks.Send(sno.LocalKills, fmt.Sprintf(ircfmt.Unescape("%s$r was killed by %s $c[grey][$r%s$c[grey]]"), target.nick, client.nick, comment)) - target.SetExitedSnomaskSent() target.Quit(quitMsg, nil) target.destroy(nil) @@ -1435,7 +1442,6 @@ func klineHandler(server *Server, client *Client, msg ircmsg.IrcMessage, rb *Res } for _, mcl := range clientsToKill { - mcl.SetExitedSnomaskSent() mcl.Quit(fmt.Sprintf(mcl.t("You have been banned from this server (%s)"), reason), nil) if mcl == client { killClient = true diff --git a/irc/nickserv.go b/irc/nickserv.go index bd979f55..1eae7ed2 100644 --- a/irc/nickserv.go +++ b/irc/nickserv.go @@ -316,6 +316,24 @@ example with $bCERT ADD $b.`, enabled: servCmdRequiresAuthEnabled, minParams: 1, }, + "suspend": { + handler: nsSuspendHandler, + help: `Syntax: $bSUSPEND $b + +SUSPEND disables an account and disconnects the associated clients.`, + helpShort: `$bSUSPEND$b disables an account and disconnects the clients`, + minParams: 1, + capabs: []string{"accreg"}, + }, + "unsuspend": { + handler: nsUnsuspendHandler, + help: `Syntax: $bUNSUSPEND $b + +UNSUSPEND reverses a previous SUSPEND, restoring access to the account.`, + helpShort: `$bUNSUSPEND$b restores access to a suspended account`, + minParams: 1, + capabs: []string{"accreg"}, + }, } ) @@ -1177,3 +1195,27 @@ func nsCertHandler(server *Server, client *Client, command string, params []stri nsNotice(rb, client.t("An error occurred")) } } + +func nsSuspendHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) { + err := server.accounts.Suspend(params[0]) + switch err { + case nil: + nsNotice(rb, fmt.Sprintf(client.t("Successfully suspended account %s"), params[0])) + case errAccountDoesNotExist: + nsNotice(rb, client.t("No such account")) + default: + nsNotice(rb, client.t("An error occurred")) + } +} + +func nsUnsuspendHandler(server *Server, client *Client, command string, params []string, rb *ResponseBuffer) { + err := server.accounts.Unsuspend(params[0]) + switch err { + case nil: + nsNotice(rb, fmt.Sprintf(client.t("Successfully un-suspended account %s"), params[0])) + case errAccountDoesNotExist: + nsNotice(rb, client.t("No such account")) + default: + nsNotice(rb, client.t("An error occurred")) + } +}