Author: Kev <klmitch@mit.edu>
authorKevin L. Mitchell <klmitch@mit.edu>
Sat, 16 Dec 2000 18:56:20 +0000 (18:56 +0000)
committerKevin L. Mitchell <klmitch@mit.edu>
Sat, 16 Dec 2000 18:56:20 +0000 (18:56 +0000)
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

13 files changed:
ChangeLog
include/client.h
include/handlers.h
include/ircd_features.h
include/msg.h
include/numeric.h
ircd/Makefile.in
ircd/client.c
ircd/ircd_features.c
ircd/m_privs.c [new file with mode: 0644]
ircd/m_whois.c
ircd/parse.c
ircd/s_err.c

index 8d6597da5ad66494e80913677bdc5c1b032fb0fd..0ec280cc051f3a255560f5a0faa1c05cbc67826d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,44 @@
+2000-12-16  Kevin L. Mitchell  <klmitch@mit.edu>
+
+       * 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 <Isomer@coders.net>
        * ircd/listener.c: added support for TOS twiddling as a 'feature'.
 
index 910ee6ed4d91b07084a73818d159b4026535f1cc..ba6217d676b23e7e137a59bfe3e2a517b4bbc0e2 100644 (file)
@@ -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 */
 
index 4779db79dc585716c7f77b79cc12052a25662301..d76b2d313108ec80431023a8f8802333f8e1c38f 100644 (file)
@@ -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*[]);
index e506df6fe9e260b1ce9a2da4739527237be4a389..dd72ea7ebbf4323653306a059df9932a87d83277 100644 (file)
@@ -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
index 0d4be4639b94e4f86a48bcde9dbbdeb078405cf2..66c5bb5739621ecf1e325c1728a2b2802a9c2c80 100644 (file)
@@ -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
  */
index ecdc6c0fd58d28a51b2608493f904a0e75a4aade..051f2bca5512e9869b85d6a2c886a0df4622f97e 100644 (file)
@@ -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 */
index b2f7a64b4356ed8d66f771c03a9788785726e951..fa1c980c34040215e04ffbe07b04bc72b6d032fc 100644 (file)
@@ -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
index 33d45ee8ed92be94f0008bb6c21e654f4064e59b..b1ed01f9aa7b4608eadd37d55c098b0ed60c672c 100644 (file)
@@ -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;
+}
index 5b45b7de158938bd54345d1288d526e8c5edebdb..4dd8d5d454fe501592a59531afc399a4bf8b49c1 100644 (file)
@@ -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 (file)
index 0000000..c2890a8
--- /dev/null
@@ -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 <assert.h>
+
+/*
+ * 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;
+}
index 5a46bdf33c93623b7c58316efb7d799638ff1927..4d9f5205a66b4dcc68a9f90408f2c91934b64ab2 100644 (file)
@@ -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
index 700eec655f2e28616e8c7a48a6e1415bad2ebc22..3f78605dd2f518fd840bd5f2695175006674d501 100644 (file)
@@ -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
index 6a55b3dce3f95b7e4b041bbd6c8dc97c0c34e947..6290bc02f695c23e63d1f960ef4c4179f345f9a0 100644 (file)
@@ -575,7 +575,7 @@ static Numeric replyTable[] = {
 /* 269 */
   { 0 },
 /* 270 */
-  { 0 },
+  { RPL_PRIVS, "%s :", "270" },
 /* 271 */
   { RPL_SILELIST, "%s %s", "271" },
 /* 272 */