From 33e5cb2e3698f5db4957373a10e7b5c019321046 Mon Sep 17 00:00:00 2001 From: "Kevin L. Mitchell" Date: Sat, 16 Dec 2000 18:56:20 +0000 Subject: [PATCH] Author: Kev Log message: Several things: First, fixed a bug in do_whois. Then defined some new features so I can turn off OPER_SET. Afterwards, make boolean options also accept "ON" and "OFF". Finally, defined a new command to report an operator's privileges. Also fixed Isomer's change to use the F_I macro properly (after adding flags to the macros...). Testing: Compiled and run and everything seems to be OK. Again, brute-force it and make sure opers have the privileges they're supposed to have. Also note that feature settings only apply to opers that just oper'd up; if you oper up, then change a feature setting, it won't affect your privileges. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@347 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 41 ++++++++++ include/client.h | 1 + include/handlers.h | 1 + include/ircd_features.h | 2 + include/msg.h | 3 + include/numeric.h | 2 +- ircd/Makefile.in | 58 +++++++------ ircd/client.c | 175 ++++++++++++++++++++++++---------------- ircd/ircd_features.c | 96 +++++++++++----------- ircd/m_privs.c | 123 ++++++++++++++++++++++++++++ ircd/m_whois.c | 3 +- ircd/parse.c | 7 ++ ircd/s_err.c | 2 +- 13 files changed, 373 insertions(+), 141 deletions(-) create mode 100644 ircd/m_privs.c diff --git a/ChangeLog b/ChangeLog index 8d6597d..0ec280c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,44 @@ +2000-12-16 Kevin L. Mitchell + + * ircd/ircd_features.c: Isomer almost got it right; you need to + use F_I(), since it's an integer value, not a boolean value. The + asserts in feature_int would catch you out... Also made the F_* + macros take flags + + * ircd/s_err.c: define RPL_PRIVS reply + + * ircd/parse.c: put new PRIVS command into command table + + * ircd/m_privs.c (mo_privs): message handler to report operator + privileges + + * ircd/ircd_features.c: declare new features OPER_SET and + LOCOP_SET; redo boolean testing routine to accept TRUE, YES, and + ON for boolean TRUE, and FALSE, NO, and OFF for boolean FALSE + + * ircd/client.c: simplify client_set_privs() with a table that + defines what features to test for; add new client_report_privs() + + * ircd/Makefile.in: compile new m_privs.c; run make depend + + * include/numeric.h (RPL_PRIVS): new reply numeric for displaying + an operator's privileges + + * include/msg.h: define new command: PRIVS + + * include/ircd_features.h: create new features OPER_SET and + LOCOP_SET for controlling access to /set + + * include/handlers.h (mo_privs): declare message handler for + reporting oper privileges + + * include/client.h (client_report_privs): declare function to + report what privileges an oper has + + * ircd/m_whois.c (do_whois): fix a bug that caused /whois to + report that a user is an oper if the oper doing the /whois had + PRIV_SEE_OPERS + 2000-12-17 Isomer * ircd/listener.c: added support for TOS twiddling as a 'feature'. diff --git a/include/client.h b/include/client.h index 910ee6e..ba6217d 100644 --- a/include/client.h +++ b/include/client.h @@ -448,6 +448,7 @@ extern void client_drop_sendq(struct Connection* con); extern void client_add_sendq(struct Connection* con, struct Connection** con_p); extern void client_set_privs(struct Client* client); +extern int client_report_privs(struct Client* to, struct Client* client); #endif /* INCLUDED_client_h */ diff --git a/include/handlers.h b/include/handlers.h index 4779db7..d76b2d3 100644 --- a/include/handlers.h +++ b/include/handlers.h @@ -146,6 +146,7 @@ extern int mo_notice(struct Client*, struct Client*, int, char*[]); extern int mo_oper(struct Client*, struct Client*, int, char*[]); extern int mo_opmode(struct Client*, struct Client*, int, char*[]); extern int mo_privmsg(struct Client*, struct Client*, int, char*[]); +extern int mo_privs(struct Client*, struct Client*, int, char*[]); extern int mo_rehash(struct Client*, struct Client*, int, char*[]); extern int mo_reset(struct Client*, struct Client*, int, char*[]); extern int mo_restart(struct Client*, struct Client*, int, char*[]); diff --git a/include/ircd_features.h b/include/ircd_features.h index e506df6..dd72ea7 100644 --- a/include/ircd_features.h +++ b/include/ircd_features.h @@ -50,6 +50,7 @@ enum Feature { FEAT_OPER_LOPMODE, FEAT_OPER_BADCHAN, FEAT_OPER_LBADCHAN, + FEAT_OPER_SET, FEAT_OPERS_SEE_IN_SECRET_CHANNELS, FEAT_LOCOP_KILL, @@ -60,6 +61,7 @@ enum Feature { FEAT_LOCOP_LJUPE, FEAT_LOCOP_LOPMODE, FEAT_LOCOP_LBADCHAN, + FEAT_LOCOP_SET, FEAT_LOCOP_SEE_IN_SECRET_CHANNELS, FEAT_LAST_F diff --git a/include/msg.h b/include/msg.h index 0d4be46..66c5bb5 100644 --- a/include/msg.h +++ b/include/msg.h @@ -334,6 +334,9 @@ struct Client; #define MSG_GET "GET" /* GET */ #define TOK_GET "GET" +#define MSG_PRIVS "PRIVS" /* PRIV */ +#define TOK_PRIVS "PRIVS" + /* * Constants */ diff --git a/include/numeric.h b/include/numeric.h index ecdc6c0..051f2bc 100644 --- a/include/numeric.h +++ b/include/numeric.h @@ -144,7 +144,7 @@ extern const struct Numeric* get_error_numeric(int err); /* RPL_START_NETSTAT 267 aircd */ /* RPL_NETSTAT 268 aircd */ /* RPL_END_NETSTAT 269 aircd */ - +#define RPL_PRIVS 270 /* Undernet extension - privs */ #define RPL_SILELIST 271 /* Undernet extension */ #define RPL_ENDOFSILELIST 272 /* Undernet extension */ /* RPL_NOTIFY 273 aircd */ diff --git a/ircd/Makefile.in b/ircd/Makefile.in index b2f7a64..fa1c980 100644 --- a/ircd/Makefile.in +++ b/ircd/Makefile.in @@ -128,6 +128,7 @@ SRC = \ m_ping.c \ m_pong.c \ m_privmsg.c \ + m_privs.c \ m_proto.c \ m_quit.c \ m_rehash.c \ @@ -319,9 +320,9 @@ class.o: class.c ../include/class.h ../include/client.h \ client.o: client.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/class.h \ - ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \ - ../include/list.h ../include/numeric.h ../include/s_conf.h \ - ../include/s_debug.h ../include/send.h + ../include/ircd.h ../include/struct.h ../include/ircd_features.h \ + ../include/ircd_reply.h ../include/list.h ../include/numeric.h \ + ../include/s_conf.h ../include/s_debug.h ../include/send.h crule.o: crule.c ../include/crule.h ../include/client.h \ ../include/ircd_defs.h ../config/config.h ../config/setup.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \ @@ -465,10 +466,11 @@ m_clearmode.o: m_clearmode.c ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \ ../include/channel.h ../include/hash.h ../include/ircd.h \ ../include/struct.h ../include/ircd_alloc.h ../include/fda.h \ - ../include/ircd_log.h ../include/ircd_reply.h \ - ../include/ircd_string.h ../include/ircd_chattr.h ../include/list.h \ - ../include/msg.h ../include/numeric.h ../include/numnicks.h \ - ../include/send.h ../include/support.h + ../include/ircd_features.h ../include/ircd_log.h \ + ../include/ircd_reply.h ../include/ircd_string.h \ + ../include/ircd_chattr.h ../include/list.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h \ + ../include/support.h m_close.o: m_close.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \ @@ -545,10 +547,11 @@ m_gline.o: m_gline.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/gline.h \ ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/s_misc.h ../include/send.h ../include/support.h + ../include/ircd_features.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_conf.h ../include/s_misc.h ../include/send.h \ + ../include/support.h m_help.o: m_help.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \ @@ -588,10 +591,11 @@ m_jupe.o: m_jupe.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/jupe.h \ ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/match.h ../include/msg.h \ - ../include/numeric.h ../include/numnicks.h ../include/s_conf.h \ - ../include/s_misc.h ../include/send.h ../include/support.h + ../include/ircd_features.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/match.h \ + ../include/msg.h ../include/numeric.h ../include/numnicks.h \ + ../include/s_conf.h ../include/s_misc.h ../include/send.h \ + ../include/support.h m_kick.o: m_kick.c ../include/channel.h ../config/config.h \ ../config/setup.h ../include/ircd_defs.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \ @@ -686,9 +690,9 @@ m_opmode.o: m_opmode.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/channel.h \ ../include/hash.h ../include/ircd.h ../include/struct.h \ - ../include/ircd_reply.h ../include/ircd_string.h \ - ../include/ircd_chattr.h ../include/msg.h ../include/numeric.h \ - ../include/numnicks.h ../include/send.h + ../include/ircd_features.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h ../include/msg.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h m_part.o: m_part.c ../include/channel.h ../config/config.h \ ../config/setup.h ../include/ircd_defs.h ../include/client.h \ ../include/dbuf.h ../include/msgq.h ../include/ircd_handler.h \ @@ -720,6 +724,12 @@ m_privmsg.o: m_privmsg.c ../include/client.h ../include/ircd_defs.h \ ../include/struct.h ../include/ircd_chattr.h ../include/ircd_relay.h \ ../include/ircd_reply.h ../include/ircd_string.h ../include/match.h \ ../include/msg.h ../include/numeric.h ../include/send.h +m_privs.o: m_privs.c ../include/client.h ../include/ircd_defs.h \ + ../config/config.h ../config/setup.h ../include/dbuf.h \ + ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \ + ../include/ircd.h ../include/struct.h ../include/ircd_reply.h \ + ../include/ircd_string.h ../include/ircd_chattr.h \ + ../include/numeric.h ../include/numnicks.h ../include/send.h m_proto.o: m_proto.c ../include/client.h ../include/ircd_defs.h \ ../config/config.h ../config/setup.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/ircd.h \ @@ -1010,12 +1020,12 @@ s_debug.o: s_debug.c ../include/s_debug.h ../config/config.h \ ../config/setup.h ../include/ircd_defs.h ../include/channel.h \ ../include/class.h ../include/client.h ../include/dbuf.h \ ../include/msgq.h ../include/ircd_handler.h ../include/hash.h \ - ../include/ircd_alloc.h ../include/fda.h ../include/ircd_log.h \ - ../include/ircd_osdep.h ../include/ircd_reply.h ../include/ircd.h \ - ../include/struct.h ../include/list.h ../include/numeric.h \ - ../include/numnicks.h ../include/res.h ../include/s_bsd.h \ - ../include/s_conf.h ../include/send.h ../include/sys.h \ - ../include/whowas.h + ../include/ircd_alloc.h ../include/fda.h ../include/ircd_features.h \ + ../include/ircd_log.h ../include/ircd_osdep.h ../include/ircd_reply.h \ + ../include/ircd.h ../include/struct.h ../include/list.h \ + ../include/numeric.h ../include/numnicks.h ../include/res.h \ + ../include/s_bsd.h ../include/s_conf.h ../include/send.h \ + ../include/sys.h ../include/whowas.h s_err.o: s_err.c ../include/numeric.h ../include/s_debug.h \ ../config/config.h ../config/setup.h ../include/ircd_defs.h \ ../include/sprintf_irc.h diff --git a/ircd/client.c b/ircd/client.c index 33d45ee..b1ed01f 100644 --- a/ircd/client.c +++ b/ircd/client.c @@ -24,6 +24,7 @@ #include "ircd_features.h" #include "ircd_reply.h" #include "list.h" +#include "msgq.h" #include "numeric.h" #include "s_conf.h" #include "s_debug.h" @@ -94,6 +95,56 @@ void client_add_sendq(struct Connection* con, struct Connection** con_p) } } +static struct { + unsigned int priv; + enum Feature feat; + unsigned int flag; +} feattab[] = { + { (PRIV_WHOX | PRIV_DISPLAY), FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_CHAN_LIMIT, FEAT_OPER_NO_CHAN_LIMIT, (FLAGS_OPER | FLAGS_LOCOP) }, + { (PRIV_MODE_LCHAN | PRIV_LOCAL_OPMODE), FEAT_OPER_MODE_LCHAN, + (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_WALK_LCHAN, FEAT_OPER_WALK_THROUGH_LMODES, + (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_DEOP_LCHAN, FEAT_NO_OPER_DEOP_LCHAN, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_SHOW_INVIS, FEAT_SHOW_INVISIBLE_USERS, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_SHOW_ALL_INVIS, FEAT_SHOW_ALL_INVISIBLE_USERS, + (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_UNLIMIT_QUERY, FEAT_UNLIMIT_OPER_QUERY, (FLAGS_OPER | FLAGS_LOCOP) }, + + { PRIV_KILL, FEAT_LOCAL_KILL_ONLY, 0 }, + { (PRIV_GLINE | PRIV_JUPE | PRIV_OPMODE | PRIV_BADCHAN), + FEAT_CONFIG_OPERCMDS, ~0 }, + + { (PRIV_PROPAGATE | PRIV_SEE_OPERS), FEAT_LAST_F, FLAGS_OPER }, + { (PRIV_KILL | PRIV_LOCAL_KILL), FEAT_OPER_KILL, FLAGS_OPER }, + { PRIV_REHASH, FEAT_OPER_REHASH, FLAGS_OPER }, + { PRIV_RESTART, FEAT_OPER_RESTART, FLAGS_OPER }, + { PRIV_DIE, FEAT_OPER_DIE, FLAGS_OPER }, + { PRIV_GLINE, FEAT_OPER_GLINE, FLAGS_OPER }, + { PRIV_LOCAL_GLINE, FEAT_OPER_LGLINE, FLAGS_OPER }, + { PRIV_JUPE, FEAT_OPER_JUPE, FLAGS_OPER }, + { PRIV_LOCAL_JUPE, FEAT_OPER_LJUPE, FLAGS_OPER }, + { PRIV_OPMODE, FEAT_OPER_OPMODE, FLAGS_OPER }, + { PRIV_LOCAL_OPMODE, FEAT_OPER_LOPMODE, FLAGS_OPER }, + { PRIV_BADCHAN, FEAT_OPER_BADCHAN, FLAGS_OPER }, + { PRIV_LOCAL_BADCHAN, FEAT_OPER_LBADCHAN, FLAGS_OPER }, + { PRIV_SET, FEAT_OPER_SET, FLAGS_OPER }, + { PRIV_SEE_CHAN, FEAT_OPERS_SEE_IN_SECRET_CHANNELS, FLAGS_OPER }, + + { PRIV_LOCAL_KILL, FEAT_LOCOP_KILL, FLAGS_LOCOP }, + { PRIV_REHASH, FEAT_LOCOP_REHASH, FLAGS_LOCOP }, + { PRIV_RESTART, FEAT_LOCOP_RESTART, FLAGS_LOCOP }, + { PRIV_DIE, FEAT_LOCOP_DIE, FLAGS_LOCOP }, + { PRIV_LOCAL_GLINE, FEAT_LOCOP_LGLINE, FLAGS_LOCOP }, + { PRIV_LOCAL_JUPE, FEAT_LOCOP_LJUPE, FLAGS_LOCOP }, + { PRIV_LOCAL_OPMODE, FEAT_LOCOP_LOPMODE, FLAGS_LOCOP }, + { PRIV_LOCAL_BADCHAN, FEAT_LOCOP_LBADCHAN, FLAGS_LOCOP }, + { PRIV_SET, FEAT_LOCOP_SET, FLAGS_LOCOP }, + { PRIV_SEE_CHAN, FEAT_LOCOP_SEE_IN_SECRET_CHANNELS, FLAGS_LOCOP }, + { 0, FEAT_LAST_F, 0 } +}; + /* client_set_privs(struct Client* client) * * Sets the privileges for opers. @@ -103,6 +154,7 @@ client_set_privs(struct Client* client) { unsigned int privs = 0; unsigned int antiprivs = 0; + int i; if (!IsAnOper(client)) { cli_privs(client) = 0; /* clear privilege mask */ @@ -114,82 +166,67 @@ client_set_privs(struct Client* client) /* This sequence is temporary until the .conf is carefully rewritten */ - privs |= (PRIV_WHOX | PRIV_DISPLAY); - if (feature_bool(FEAT_OPER_NO_CHAN_LIMIT)) - privs |= PRIV_CHAN_LIMIT; - if (feature_bool(FEAT_OPER_MODE_LCHAN)) - privs |= (PRIV_MODE_LCHAN | PRIV_LOCAL_OPMODE); - if (feature_bool(FEAT_OPER_WALK_THROUGH_LMODES)) - privs |= PRIV_WALK_LCHAN; - if (feature_bool(FEAT_NO_OPER_DEOP_LCHAN)) - privs |= PRIV_DEOP_LCHAN; - if (feature_bool(FEAT_SHOW_INVISIBLE_USERS)) - privs |= PRIV_SHOW_INVIS; - if (feature_bool(FEAT_SHOW_ALL_INVISIBLE_USERS)) - privs |= PRIV_SHOW_ALL_INVIS; - if (feature_bool(FEAT_UNLIMIT_OPER_QUERY)) - privs |= PRIV_UNLIMIT_QUERY; - if (feature_bool(FEAT_LOCAL_KILL_ONLY)) - antiprivs |= PRIV_KILL; - if (!feature_bool(FEAT_CONFIG_OPERCMDS)) - antiprivs |= (PRIV_GLINE | PRIV_JUPE | PRIV_OPMODE | PRIV_BADCHAN); - - if (IsOper(client)) { - privs |= (PRIV_SET | PRIV_PROPAGATE | PRIV_SEE_OPERS); - if (feature_bool(FEAT_OPER_KILL)) - privs |= (PRIV_KILL | PRIV_LOCAL_KILL); - if (feature_bool(FEAT_OPER_REHASH)) - privs |= PRIV_REHASH; - if (feature_bool(FEAT_OPER_RESTART)) - privs |= PRIV_RESTART; - if (feature_bool(FEAT_OPER_DIE)) - privs |= PRIV_DIE; - if (feature_bool(FEAT_OPER_GLINE)) - privs |= PRIV_GLINE; - if (feature_bool(FEAT_OPER_LGLINE)) - privs |= PRIV_LOCAL_GLINE; - if (feature_bool(FEAT_OPER_JUPE)) - privs |= PRIV_JUPE; - if (feature_bool(FEAT_OPER_LJUPE)) - privs |= PRIV_LOCAL_JUPE; - if (feature_bool(FEAT_OPER_OPMODE)) - privs |= PRIV_OPMODE; - if (feature_bool(FEAT_OPER_LOPMODE)) - privs |= PRIV_LOCAL_OPMODE; - if (feature_bool(FEAT_OPER_BADCHAN)) - privs |= PRIV_BADCHAN; - if (feature_bool(FEAT_OPER_LBADCHAN)) - privs |= PRIV_LOCAL_BADCHAN; - if (feature_bool(FEAT_OPERS_SEE_IN_SECRET_CHANNELS)) - privs |= PRIV_SEE_CHAN; - } else { /* is a local operator */ - if (feature_bool(FEAT_LOCOP_KILL)) - privs |= PRIV_LOCAL_KILL; - if (feature_bool(FEAT_LOCOP_REHASH)) - privs |= PRIV_REHASH; - if (feature_bool(FEAT_LOCOP_RESTART)) - privs |= PRIV_RESTART; - if (feature_bool(FEAT_LOCOP_DIE)) - privs |= PRIV_DIE; - if (feature_bool(FEAT_LOCOP_LGLINE)) - privs |= PRIV_LOCAL_GLINE; - if (feature_bool(FEAT_LOCOP_LJUPE)) - privs |= PRIV_LOCAL_JUPE; - if (feature_bool(FEAT_LOCOP_LOPMODE)) - privs |= PRIV_LOCAL_OPMODE; - if (feature_bool(FEAT_LOCOP_LBADCHAN)) - privs |= PRIV_LOCAL_BADCHAN; - if (feature_bool(FEAT_LOCOP_SEE_IN_SECRET_CHANNELS)) - privs |= PRIV_SEE_CHAN; + for (i = 0; feattab[i].priv; i++) { + if (feattab[i].flag == 0) { + if (feature_bool(feattab[i].feat)) + antiprivs |= feattab[i].priv; + } else if (feattab[i].flag == ~0) { + if (!feature_bool(feattab[i].feat)) + antiprivs |= feattab[i].priv; + } else if (cli_flags(client) & feattab[i].flag) { + if (feattab[i].feat == FEAT_LAST_F || + feature_bool(feattab[i].feat)) + privs |= feattab[i].priv; + } } /* This is the end of the gross section */ if (privs & PRIV_PROPAGATE) - privs |= PRIV_DISPLAY; - else + privs |= PRIV_DISPLAY; /* force propagating opers to display */ + else /* if they don't propagate oper status, prevent desyncs */ antiprivs |= (PRIV_KILL | PRIV_GLINE | PRIV_JUPE | PRIV_OPMODE | PRIV_BADCHAN); cli_privs(client) = privs & ~antiprivs; } + +static struct { + char *name; + unsigned int priv; +} privtab[] = { +#define P(priv) { #priv, PRIV_ ## priv } + P(CHAN_LIMIT), P(MODE_LCHAN), P(WALK_LCHAN), P(DEOP_LCHAN), + P(SHOW_INVIS), P(SHOW_ALL_INVIS), P(UNLIMIT_QUERY), P(KILL), + P(LOCAL_KILL), P(REHASH), P(RESTART), P(DIE), + P(GLINE), P(LOCAL_GLINE), P(JUPE), P(LOCAL_JUPE), + P(OPMODE), P(LOCAL_OPMODE), P(SET), P(WHOX), + P(BADCHAN), P(LOCAL_BADCHAN), P(SEE_CHAN), P(PROPAGATE), + P(DISPLAY), P(SEE_OPERS), +#undef P + { 0, 0 } +}; + +/* client_report_privs(struct Client *to, struct Client *client) + * + * Sends a summary of the oper's privileges to the oper. + */ +int +client_report_privs(struct Client *to, struct Client *client) +{ + struct MsgBuf *mb; + int found1 = 0; + int i; + + mb = msgq_make(to, rpl_str(RPL_PRIVS), cli_name(&me), cli_name(to), + cli_name(client)); + + for (i = 0; privtab[i].name; i++) + if (cli_privs(client) & privtab[i].priv) + msgq_append(0, mb, "%s%s", found1++ ? " " : "", privtab[i].name); + + send_buffer(to, mb, 0); /* send response */ + msgq_clean(mb); + + return 0; +} diff --git a/ircd/ircd_features.c b/ircd/ircd_features.c index 5b45b7d..4dd8d5d 100644 --- a/ircd/ircd_features.c +++ b/ircd/ircd_features.c @@ -207,10 +207,12 @@ static struct FeatureDesc { #define F(type, flags, v_int, v_str, set, reset, get, unmark, mark, report) \ { FEAT_ ## type, #type, (flags), 0, (v_int), 0, (v_str), \ (set), (reset), (get), (unmark), (mark), (report) } -#define F_I(type, v_int) \ - { FEAT_ ## type, #type, FEAT_INT, 0, (v_int), 0, 0, 0, 0, 0, 0, 0, 0 } -#define F_B(type, v_int) \ - { FEAT_ ## type, #type, FEAT_BOOL, 0, (v_int), 0, 0, 0, 0, 0, 0, 0, 0 } +#define F_I(type, flags, v_int) \ + { FEAT_ ## type, #type, FEAT_INT | (flags), 0, (v_int), 0, 0, \ + 0, 0, 0, 0, 0, 0 } +#define F_B(type, flags, v_int) \ + { FEAT_ ## type, #type, FEAT_BOOL | (flags), 0, (v_int), 0, 0, \ + 0, 0, 0, 0, 0, 0 } #define F_S(type, flags, v_int) \ { FEAT_ ## type, #type, FEAT_STR | (flags), 0, 0, 0, (v_str), \ 0, 0, 0, 0, 0, 0 } @@ -219,41 +221,43 @@ static struct FeatureDesc { feature_log_set, feature_log_reset, feature_log_get, log_feature_unmark, log_feature_mark, log_feature_report), - F_B(OPER_NO_CHAN_LIMIT, 1), - F_B(OPER_MODE_LCHAN, 1), - F_B(OPER_WALK_THROUGH_LMODES, 0), - F_B(NO_OPER_DEOP_LCHAN, 0), - F_B(SHOW_INVISIBLE_USERS, 1), - F_B(SHOW_ALL_INVISIBLE_USERS, 1), - F_B(UNLIMIT_OPER_QUERY, 0), - F_B(LOCAL_KILL_ONLY, 0), - F_B(TOS_SERVER,0x08), - F_B(TOS_CLIENT,0x08), - F_B(CONFIG_OPERCMDS, 1), /* XXX change default before release */ - - F_B(OPER_KILL, 1), - F_B(OPER_REHASH, 1), - F_B(OPER_RESTART, 1), - F_B(OPER_DIE, 1), - F_B(OPER_GLINE, 1), - F_B(OPER_LGLINE, 1), - F_B(OPER_JUPE, 1), - F_B(OPER_LJUPE, 1), - F_B(OPER_OPMODE, 1), - F_B(OPER_LOPMODE, 1), - F_B(OPER_BADCHAN, 0), - F_B(OPER_LBADCHAN, 0), - F_B(OPERS_SEE_IN_SECRET_CHANNELS, 1), - - F_B(LOCOP_KILL, 0), - F_B(LOCOP_REHASH, 1), - F_B(LOCOP_RESTART, 0), - F_B(LOCOP_DIE, 0), - F_B(LOCOP_LGLINE, 1), - F_B(LOCOP_LJUPE, 1), - F_B(LOCOP_LOPMODE, 1), - F_B(LOCOP_LBADCHAN, 0), - F_B(LOCOP_SEE_IN_SECRET_CHANNELS, 0), + F_B(OPER_NO_CHAN_LIMIT, 0, 1), + F_B(OPER_MODE_LCHAN, 0, 1), + F_B(OPER_WALK_THROUGH_LMODES, 0, 0), + F_B(NO_OPER_DEOP_LCHAN, 0, 0), + F_B(SHOW_INVISIBLE_USERS, 0, 1), + F_B(SHOW_ALL_INVISIBLE_USERS, 0, 1), + F_B(UNLIMIT_OPER_QUERY, 0, 0), + F_B(LOCAL_KILL_ONLY, 0, 0), + F_I(TOS_SERVER, 0, 0x08), + F_I(TOS_CLIENT, 0, 0x08), + F_B(CONFIG_OPERCMDS, 0, 1), /* XXX change default before release */ + + F_B(OPER_KILL, 0, 1), + F_B(OPER_REHASH, 0, 1), + F_B(OPER_RESTART, 0, 1), + F_B(OPER_DIE, 0, 1), + F_B(OPER_GLINE, 0, 1), + F_B(OPER_LGLINE, 0, 1), + F_B(OPER_JUPE, 0, 1), + F_B(OPER_LJUPE, 0, 1), + F_B(OPER_OPMODE, 0, 1), + F_B(OPER_LOPMODE, 0, 1), + F_B(OPER_BADCHAN, 0, 0), + F_B(OPER_LBADCHAN, 0, 0), + F_B(OPER_SET, 0, 1), + F_B(OPERS_SEE_IN_SECRET_CHANNELS, 0, 1), + + F_B(LOCOP_KILL, 0, 0), + F_B(LOCOP_REHASH, 0, 1), + F_B(LOCOP_RESTART, 0, 0), + F_B(LOCOP_DIE, 0, 0), + F_B(LOCOP_LGLINE, 0, 1), + F_B(LOCOP_LJUPE, 0, 1), + F_B(LOCOP_LOPMODE, 0, 1), + F_B(LOCOP_LBADCHAN, 0, 0), + F_B(LOCOP_SET, 0, 0), + F_B(LOCOP_SEE_IN_SECRET_CHANNELS, 0, 0), #undef F_S #undef F_B @@ -324,13 +328,15 @@ feature_set(struct Client* from, const char* const* fields, int count) feat->v_int = feat->def_int; feat->flags &= ~FEAT_MARK; } else { /* figure out the value and whether to mark it */ - if (!ircd_strncmp(fields[1], "TRUE", strlen(fields[1]))) + if (!ircd_strncmp(fields[1], "TRUE", strlen(fields[1])) || + !ircd_strncmp(fields[1], "YES", strlen(fields[1])) || + (strlen(fields[1]) >= 2 && + !ircd_strncmp(fields[1], "ON", strlen(fields[1])))) feat->v_int = 1; - else if (!ircd_strncmp(fields[1], "YES", strlen(fields[1]))) - feat->v_int = 1; - else if (!ircd_strncmp(fields[1], "FALSE", strlen(fields[1]))) - feat->v_int = 0; - else if (!ircd_strncmp(fields[1], "NO", strlen(fields[1]))) + else if (!ircd_strncmp(fields[1], "FALSE", strlen(fields[1])) || + !ircd_strncmp(fields[1], "NO", strlen(fields[1])) || + (strlen(fields[1]) >= 2 && + !ircd_strncmp(fields[1], "OFF", strlen(fields[1])))) feat->v_int = 0; else if (from) /* report an error... */ return send_reply(from, ERR_BADFEATVALUE, fields[1], feat->type); diff --git a/ircd/m_privs.c b/ircd/m_privs.c new file mode 100644 index 0000000..c2890a8 --- /dev/null +++ b/ircd/m_privs.c @@ -0,0 +1,123 @@ +/* + * IRC - Internet Relay Chat, ircd/m_privs.c + * Copyright (C) 1990 Jarkko Oikarinen and + * University of Oulu, Computing Center + * + * See file AUTHORS in IRC package for additional names of + * the programmers. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 1, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * $Id$ + */ + +/* + * m_functions execute protocol messages on this server: + * + * cptr is always NON-NULL, pointing to a *LOCAL* client + * structure (with an open socket connected!). This + * identifies the physical socket where the message + * originated (or which caused the m_function to be + * executed--some m_functions may call others...). + * + * sptr is the source of the message, defined by the + * prefix part of the message if present. If not + * or prefix not found, then sptr==cptr. + * + * (!IsServer(cptr)) => (cptr == sptr), because + * prefixes are taken *only* from servers... + * + * (IsServer(cptr)) + * (sptr == cptr) => the message didn't + * have the prefix. + * + * (sptr != cptr && IsServer(sptr) means + * the prefix specified servername. (?) + * + * (sptr != cptr && !IsServer(sptr) means + * that message originated from a remote + * user (not local). + * + * combining + * + * (!IsServer(sptr)) means that, sptr can safely + * taken as defining the target structure of the + * message in this server. + * + * *Always* true (if 'parse' and others are working correct): + * + * 1) sptr->from == cptr (note: cptr->from == cptr) + * + * 2) MyConnect(sptr) <=> sptr == cptr (e.g. sptr + * *cannot* be a local connection, unless it's + * actually cptr!). [MyConnect(x) should probably + * be defined as (x == x->from) --msa ] + * + * parc number of variable parameter strings (if zero, + * parv is allowed to be NULL) + * + * parv a NULL terminated list of parameter pointers, + * + * parv[0], sender (prefix string), if not present + * this points to an empty string. + * parv[1]...parv[parc-1] + * pointers to additional parameters + * parv[parc] == NULL, *always* + * + * note: it is guaranteed that parv[0]..parv[parc-1] are all + * non-NULL pointers. + */ +#if 0 +/* + * No need to include handlers.h here the signatures must match + * and we don't need to force a rebuild of all the handlers everytime + * we add a new one to the list. --Bleep + */ +#include "handlers.h" +#endif /* 0 */ +#include "client.h" +#include "hash.h" +#include "ircd.h" +#include "ircd_reply.h" +#include "ircd_string.h" +#include "numeric.h" +#include "numnicks.h" +#include "send.h" + +#include + +/* + * mo_privs - report operator privileges + */ +int mo_privs(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) +{ + struct Client *acptr; + char *name; + char *p = 0; + int i; + + if (parc < 2) + return need_more_params(sptr, "PRIVS"); + + for (i = 1; i < parc; i++) { + for (name = ircd_strtok(&p, parv[i], " "); name; + name = ircd_strtok(&p, 0, " ")) { + if ((acptr = FindUser(name))) + client_report_privs(sptr, acptr); + } + } + + return 0; +} diff --git a/ircd/m_whois.c b/ircd/m_whois.c index 5a46bdf..4d9f520 100644 --- a/ircd/m_whois.c +++ b/ircd/m_whois.c @@ -194,7 +194,8 @@ static void do_whois(struct Client* sptr, struct Client *acptr) if (user->away) send_reply(sptr, RPL_AWAY, name, user->away); - if (HasPriv(acptr, PRIV_DISPLAY) || HasPriv(sptr, PRIV_SEE_OPERS)) + if (IsAnOper(acptr) && (HasPriv(acptr, PRIV_DISPLAY) || + HasPriv(sptr, PRIV_SEE_OPERS))) send_reply(sptr, RPL_WHOISOPERATOR, name); /* Hint: if your looking to add more flags to a user, eg +h, here's diff --git a/ircd/parse.c b/ircd/parse.c index 700eec6..3f78605 100644 --- a/ircd/parse.c +++ b/ircd/parse.c @@ -548,6 +548,13 @@ struct Message msgtab[] = { /* UNREG, CLIENT, SERVER, OPER, SERVICE */ { m_unregistered, m_not_oper, m_ignore, mo_get, m_ignore } }, + { + MSG_PRIVS, + TOK_PRIVS, + 0, MAXPARA, MFLG_SLOW, 0, + /* UNREG, CLIENT, SERVER, OPER, SERVICE */ + { m_unregistered, m_not_oper, m_ignore, mo_privs, m_ignore } + }, /* This command is an alias for QUIT during the unregistered part of * of the server. This is because someone jumping via a broken web * proxy will send a 'POST' as their first command - which we will diff --git a/ircd/s_err.c b/ircd/s_err.c index 6a55b3d..6290bc0 100644 --- a/ircd/s_err.c +++ b/ircd/s_err.c @@ -575,7 +575,7 @@ static Numeric replyTable[] = { /* 269 */ { 0 }, /* 270 */ - { 0 }, + { RPL_PRIVS, "%s :", "270" }, /* 271 */ { RPL_SILELIST, "%s %s", "271" }, /* 272 */ -- 2.20.1