Rework oper hiding
As it stands, oper hiding is rather messy and inconsistent. Add SeesOper(target, source), which is true iff target should appear as an oper to source. If I haven't missed something, all commands that reveal oper status now use the same logic. general::hide_opers_in_whois is a special case, and affects /whois only. general::hide_opers is introduced, and has the same effect as giving everyone oper:hidden. All commands that reveal oper status respect both.
This commit is contained in:
parent
f7f1c50494
commit
1123eefcb0
10 changed files with 27 additions and 18 deletions
|
@ -239,6 +239,7 @@ struct config_file_entry
|
||||||
int certfp_method;
|
int certfp_method;
|
||||||
|
|
||||||
int hide_opers_in_whois;
|
int hide_opers_in_whois;
|
||||||
|
int hide_opers;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct config_channel_entry
|
struct config_channel_entry
|
||||||
|
|
|
@ -166,6 +166,8 @@ extern void cluster_generic(struct Client *, const char *, int cltype,
|
||||||
#define IsOperRemoteBan(x) (HasPrivilege((x), "oper:remoteban"))
|
#define IsOperRemoteBan(x) (HasPrivilege((x), "oper:remoteban"))
|
||||||
#define IsOperMassNotice(x) (HasPrivilege((x), "oper:mass_notice"))
|
#define IsOperMassNotice(x) (HasPrivilege((x), "oper:mass_notice"))
|
||||||
|
|
||||||
|
#define SeesOper(target, source) (IsOper((target)) && (!ConfigFileEntry.hide_opers && !HasPrivilege((target), "oper:hidden") || IsOper((source))))
|
||||||
|
|
||||||
extern struct oper_conf *make_oper_conf(void);
|
extern struct oper_conf *make_oper_conf(void);
|
||||||
extern void free_oper_conf(struct oper_conf *);
|
extern void free_oper_conf(struct oper_conf *);
|
||||||
extern void clear_oper_conf(void);
|
extern void clear_oper_conf(void);
|
||||||
|
|
|
@ -2797,6 +2797,7 @@ static struct ConfEntry conf_general_table[] =
|
||||||
{ "max_ratelimit_tokens", CF_INT, NULL, 0, &ConfigFileEntry.max_ratelimit_tokens },
|
{ "max_ratelimit_tokens", CF_INT, NULL, 0, &ConfigFileEntry.max_ratelimit_tokens },
|
||||||
{ "away_interval", CF_INT, NULL, 0, &ConfigFileEntry.away_interval },
|
{ "away_interval", CF_INT, NULL, 0, &ConfigFileEntry.away_interval },
|
||||||
{ "hide_opers_in_whois", CF_YESNO, NULL, 0, &ConfigFileEntry.hide_opers_in_whois },
|
{ "hide_opers_in_whois", CF_YESNO, NULL, 0, &ConfigFileEntry.hide_opers_in_whois },
|
||||||
|
{ "hide_opers", CF_YESNO, NULL, 0, &ConfigFileEntry.hide_opers },
|
||||||
{ "certfp_method", CF_STRING, conf_set_general_certfp_method, 0, NULL },
|
{ "certfp_method", CF_STRING, conf_set_general_certfp_method, 0, NULL },
|
||||||
{ "\0", 0, NULL, 0, NULL }
|
{ "\0", 0, NULL, 0, NULL }
|
||||||
};
|
};
|
||||||
|
|
|
@ -809,6 +809,7 @@ set_default_conf(void)
|
||||||
ConfigFileEntry.nicklen = NICKLEN;
|
ConfigFileEntry.nicklen = NICKLEN;
|
||||||
ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_CERT_SHA1;
|
ConfigFileEntry.certfp_method = RB_SSL_CERTFP_METH_CERT_SHA1;
|
||||||
ConfigFileEntry.hide_opers_in_whois = 0;
|
ConfigFileEntry.hide_opers_in_whois = 0;
|
||||||
|
ConfigFileEntry.hide_opers = 0;
|
||||||
|
|
||||||
if (!alias_dict)
|
if (!alias_dict)
|
||||||
alias_dict = rb_dictionary_create("alias", rb_strcasecmp);
|
alias_dict = rb_dictionary_create("alias", rb_strcasecmp);
|
||||||
|
|
|
@ -167,7 +167,7 @@ do_etrace(struct Client *source_p, int ipv4, int ipv6)
|
||||||
|
|
||||||
sendto_one(source_p, form_str(RPL_ETRACE),
|
sendto_one(source_p, form_str(RPL_ETRACE),
|
||||||
me.name, source_p->name,
|
me.name, source_p->name,
|
||||||
IsOper(target_p) ? "Oper" : "User",
|
SeesOper(target_p, source_p) ? "Oper" : "User",
|
||||||
get_client_class(target_p),
|
get_client_class(target_p),
|
||||||
target_p->name, target_p->username, target_p->host,
|
target_p->name, target_p->username, target_p->host,
|
||||||
show_ip(source_p, target_p) ? target_p->sockhost : "255.255.255.255",
|
show_ip(source_p, target_p) ? target_p->sockhost : "255.255.255.255",
|
||||||
|
@ -206,14 +206,14 @@ do_single_etrace(struct Client *source_p, struct Client *target_p)
|
||||||
if(!show_ip(source_p, target_p))
|
if(!show_ip(source_p, target_p))
|
||||||
sendto_one(source_p, form_str(RPL_ETRACEFULL),
|
sendto_one(source_p, form_str(RPL_ETRACEFULL),
|
||||||
me.name, source_p->name,
|
me.name, source_p->name,
|
||||||
IsOper(target_p) ? "Oper" : "User",
|
SeesOper(target_p, source_p) ? "Oper" : "User",
|
||||||
get_client_class(target_p),
|
get_client_class(target_p),
|
||||||
target_p->name, target_p->username, target_p->host,
|
target_p->name, target_p->username, target_p->host,
|
||||||
"255.255.255.255", "<hidden> <hidden>", target_p->info);
|
"255.255.255.255", "<hidden> <hidden>", target_p->info);
|
||||||
else
|
else
|
||||||
sendto_one(source_p, form_str(RPL_ETRACEFULL),
|
sendto_one(source_p, form_str(RPL_ETRACEFULL),
|
||||||
me.name, source_p->name,
|
me.name, source_p->name,
|
||||||
IsOper(target_p) ? "Oper" : "User",
|
SeesOper(target_p, source_p) ? "Oper" : "User",
|
||||||
get_client_class(target_p),
|
get_client_class(target_p),
|
||||||
target_p->name, target_p->username,
|
target_p->name, target_p->username,
|
||||||
target_p->host, target_p->sockhost,
|
target_p->host, target_p->sockhost,
|
||||||
|
@ -278,7 +278,7 @@ m_chantrace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sou
|
||||||
|
|
||||||
sendto_one(source_p, form_str(RPL_ETRACE),
|
sendto_one(source_p, form_str(RPL_ETRACE),
|
||||||
me.name, source_p->name,
|
me.name, source_p->name,
|
||||||
IsOper(target_p) ? "Oper" : "User",
|
SeesOper(target_p, source_p) ? "Oper" : "User",
|
||||||
/* class field -- pretend its server.. */
|
/* class field -- pretend its server.. */
|
||||||
target_p->servptr->name,
|
target_p->servptr->name,
|
||||||
target_p->name, target_p->username, target_p->host,
|
target_p->name, target_p->username, target_p->host,
|
||||||
|
@ -323,7 +323,7 @@ match_masktrace(struct Client *source_p, rb_dlink_list *list,
|
||||||
|
|
||||||
sendto_one(source_p, form_str(RPL_ETRACE),
|
sendto_one(source_p, form_str(RPL_ETRACE),
|
||||||
me.name, source_p->name,
|
me.name, source_p->name,
|
||||||
IsOper(target_p) ? "Oper" : "User",
|
SeesOper(target_p, source_p) ? "Oper" : "User",
|
||||||
/* class field -- pretend its server.. */
|
/* class field -- pretend its server.. */
|
||||||
target_p->servptr->name,
|
target_p->servptr->name,
|
||||||
target_p->name, target_p->username, target_p->host,
|
target_p->name, target_p->username, target_p->host,
|
||||||
|
|
|
@ -830,7 +830,7 @@ stats_operedup (struct Client *source_p)
|
||||||
{
|
{
|
||||||
target_p = oper_ptr->data;
|
target_p = oper_ptr->data;
|
||||||
|
|
||||||
if(IsOperInvis(target_p) && !IsOper(source_p))
|
if(!SeesOper(target_p, source_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(target_p->user->away)
|
if(target_p->user->away)
|
||||||
|
|
|
@ -204,6 +204,9 @@ m_trace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
if(!doall && wilds && (match(tname, target_p->name) == 0))
|
if(!doall && wilds && (match(tname, target_p->name) == 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if(!SeesOper(target_p, source_p))
|
||||||
|
continue;
|
||||||
|
|
||||||
report_this_status(source_p, target_p);
|
report_this_status(source_p, target_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,14 +236,14 @@ m_trace(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_
|
||||||
target_p = ptr->data;
|
target_p = ptr->data;
|
||||||
|
|
||||||
/* dont show invisible users to remote opers */
|
/* dont show invisible users to remote opers */
|
||||||
if(IsInvisible(target_p) && dow && !MyConnect(source_p) && !IsOper(target_p))
|
if(IsInvisible(target_p) && dow && !MyConnect(source_p) && !SeesOper(target_p, source_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(!doall && wilds && !match(tname, target_p->name))
|
if(!doall && wilds && !match(tname, target_p->name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* remote opers may not see invisible normal users */
|
/* remote opers may not see invisible normal users */
|
||||||
if(dow && !MyConnect(source_p) && !IsOper(target_p) &&
|
if(dow && !MyConnect(source_p) && !SeesOper(target_p, source_p) &&
|
||||||
IsInvisible(target_p))
|
IsInvisible(target_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -379,8 +382,8 @@ report_this_status(struct Client *source_p, struct Client *target_p)
|
||||||
case STAT_CLIENT:
|
case STAT_CLIENT:
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p,
|
sendto_one_numeric(source_p,
|
||||||
IsOper(target_p) ? RPL_TRACEOPERATOR : RPL_TRACEUSER,
|
SeesOper(target_p, source_p) ? RPL_TRACEOPERATOR : RPL_TRACEUSER,
|
||||||
IsOper(target_p) ? form_str(RPL_TRACEOPERATOR) : form_str(RPL_TRACEUSER),
|
SeesOper(target_p, source_p) ? form_str(RPL_TRACEOPERATOR) : form_str(RPL_TRACEUSER),
|
||||||
class_name, name,
|
class_name, name,
|
||||||
show_ip(source_p, target_p) ? ip : empty_sockhost,
|
show_ip(source_p, target_p) ? ip : empty_sockhost,
|
||||||
(unsigned long)(rb_current_time() - target_p->localClient->lasttime),
|
(unsigned long)(rb_current_time() - target_p->localClient->lasttime),
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "modules.h"
|
#include "modules.h"
|
||||||
#include "s_conf.h"
|
#include "s_conf.h"
|
||||||
|
#include "s_newconf.h"
|
||||||
|
|
||||||
static const char userhost_desc[] =
|
static const char userhost_desc[] =
|
||||||
"Provides the USERHOST command to show a user's host";
|
"Provides the USERHOST command to show a user's host";
|
||||||
|
@ -85,7 +86,7 @@ m_userhost(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sour
|
||||||
{
|
{
|
||||||
rl = sprintf(response, "%s%s=%c%s@%s ",
|
rl = sprintf(response, "%s%s=%c%s@%s ",
|
||||||
target_p->name,
|
target_p->name,
|
||||||
IsOper(target_p) ? "*" : "",
|
SeesOper(target_p, source_p) ? "*" : "",
|
||||||
(target_p->user->away) ? '-' : '+',
|
(target_p->user->away) ? '-' : '+',
|
||||||
target_p->username,
|
target_p->username,
|
||||||
target_p->sockhost);
|
target_p->sockhost);
|
||||||
|
@ -94,7 +95,7 @@ m_userhost(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *sour
|
||||||
{
|
{
|
||||||
rl = sprintf(response, "%s%s=%c%s@%s ",
|
rl = sprintf(response, "%s%s=%c%s@%s ",
|
||||||
target_p->name,
|
target_p->name,
|
||||||
IsOper(target_p) ? "*" : "",
|
SeesOper(target_p, source_p) ? "*" : "",
|
||||||
(target_p->user->away) ? '-' : '+',
|
(target_p->user->away) ? '-' : '+',
|
||||||
target_p->username, target_p->host);
|
target_p->username, target_p->host);
|
||||||
}
|
}
|
||||||
|
|
|
@ -218,7 +218,7 @@ m_who(struct MsgBuf *msgbuf_p, struct Client *client_p, struct Client *source_p,
|
||||||
/* '/who nick' */
|
/* '/who nick' */
|
||||||
|
|
||||||
if(((target_p = find_named_person(mask)) != NULL) &&
|
if(((target_p = find_named_person(mask)) != NULL) &&
|
||||||
(!server_oper || IsOper(target_p)))
|
(!server_oper || SeesOper(target_p, source_p)))
|
||||||
{
|
{
|
||||||
int isinvis = 0;
|
int isinvis = 0;
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ who_common_channel(struct Client *source_p, struct Channel *chptr,
|
||||||
if(!IsInvisible(target_p) || IsMarked(target_p))
|
if(!IsInvisible(target_p) || IsMarked(target_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(server_oper && !IsOper(target_p))
|
if(server_oper && !SeesOper(target_p, source_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
SetMark(target_p);
|
SetMark(target_p);
|
||||||
|
@ -387,7 +387,7 @@ who_global(struct Client *source_p, const char *mask, int server_oper, int opers
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(server_oper && !IsOper(target_p))
|
if(server_oper && !SeesOper(target_p, source_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(maxmatches > 0)
|
if(maxmatches > 0)
|
||||||
|
@ -435,7 +435,7 @@ do_who_on_channel(struct Client *source_p, struct Channel *chptr,
|
||||||
msptr = ptr->data;
|
msptr = ptr->data;
|
||||||
target_p = msptr->client_p;
|
target_p = msptr->client_p;
|
||||||
|
|
||||||
if(server_oper && !IsOper(target_p))
|
if(server_oper && !SeesOper(target_p, source_p))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(member || !IsInvisible(target_p))
|
if(member || !IsInvisible(target_p))
|
||||||
|
@ -488,7 +488,7 @@ do_who(struct Client *source_p, struct Client *target_p, struct membership *mspt
|
||||||
const char *q;
|
const char *q;
|
||||||
|
|
||||||
sprintf(status, "%c%s%s",
|
sprintf(status, "%c%s%s",
|
||||||
target_p->user->away ? 'G' : 'H', IsOper(target_p) ? "*" : "", msptr ? find_channel_status(msptr, fmt->fields || IsCapable(source_p, CLICAP_MULTI_PREFIX)) : "");
|
target_p->user->away ? 'G' : 'H', SeesOper(target_p, source_p) ? "*" : "", msptr ? find_channel_status(msptr, fmt->fields || IsCapable(source_p, CLICAP_MULTI_PREFIX)) : "");
|
||||||
|
|
||||||
if (fmt->fields == 0)
|
if (fmt->fields == 0)
|
||||||
sendto_one(source_p, form_str(RPL_WHOREPLY), me.name,
|
sendto_one(source_p, form_str(RPL_WHOREPLY), me.name,
|
||||||
|
|
|
@ -309,7 +309,7 @@ single_whois(struct Client *source_p, struct Client *target_p, int operspy)
|
||||||
sendto_one_numeric(source_p, RPL_AWAY, form_str(RPL_AWAY),
|
sendto_one_numeric(source_p, RPL_AWAY, form_str(RPL_AWAY),
|
||||||
target_p->name, target_p->user->away);
|
target_p->name, target_p->user->away);
|
||||||
|
|
||||||
if(IsOper(target_p) && (!ConfigFileEntry.hide_opers_in_whois || IsOper(source_p)))
|
if((!ConfigFileEntry.hide_opers_in_whois || IsOper(source_p)) && SeesOper(target_p, source_p))
|
||||||
{
|
{
|
||||||
sendto_one_numeric(source_p, RPL_WHOISOPERATOR, form_str(RPL_WHOISOPERATOR),
|
sendto_one_numeric(source_p, RPL_WHOISOPERATOR, form_str(RPL_WHOISOPERATOR),
|
||||||
target_p->name,
|
target_p->name,
|
||||||
|
|
Loading…
Reference in a new issue