s2s: enforce servprotect on a remote KILL and rank-vs-victim on a remote KICK (matching the local paths)

This commit is contained in:
Jean Chevronnet 2026-08-17 19:38:58 +00:00
parent da36d5c32a
commit 73f8ff58ed
2 changed files with 24 additions and 0 deletions

View file

@ -514,6 +514,20 @@ impl Command for Kick {
);
return CmdResult::Fail;
}
// can't kick a remote member who out-ranks you (as for local victims)
let vrank = s.channels[&key]
.rmembers
.get(&vuuid)
.map(|m| m.rank())
.unwrap_or(0);
if s.rank(uid, &key) < vrank {
s.numeric(
uid,
ERR_CHANOPRIVSNEEDED,
&format!("{chan} :You cannot kick a user of higher rank"),
);
return CmdResult::Fail;
}
let kicker = s.users[&uid].nick.clone();
let reason = params.get(2).cloned().unwrap_or(kicker);
let prefix = s.users[&uid].prefix();

View file

@ -182,6 +182,16 @@ impl Command for Kill {
let Some(tuid) = s.find_nick(target) else {
// remote target: route the KILL toward the server that owns it
if let Some((uuid, _)) = s.find_remote(target) {
// servprotect (+k): a network service can't be killed, even remotely
let protected = s.uuid_is_service(&uuid)
|| s.remote_users
.get(&uuid)
.map(|r| r.modes.contains('k'))
.unwrap_or(false);
if protected {
s.numeric(uid, ERR_NOPRIVILEGES, ":You cannot KILL a network service");
return CmdResult::Fail;
}
let (killer_uuid, killer) = s
.users
.get(&uid)