From 4d8088c386c23049fcfe856e04bc6b4353873044 Mon Sep 17 00:00:00 2001 From: Eric Mertens Date: Sat, 12 Jun 2021 11:04:33 -0700 Subject: [PATCH] Allow auth{} to apply extra umodes (#202) Allow auth{} to apply extra umodes Co-authored-by: Doug Freed Co-authored-by: Ed Kellett --- doc/oper-guide/config.rst | 3 ++ include/s_conf.h | 1 + ircd/newconf.c | 92 ++++++++++++++++++++++++--------------- ircd/s_user.c | 8 +++- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/doc/oper-guide/config.rst b/doc/oper-guide/config.rst index 61368847..067bf654 100644 --- a/doc/oper-guide/config.rst +++ b/doc/oper-guide/config.rst @@ -255,6 +255,9 @@ flags class A name of a class to put users matching this auth{} block into. +umodes + Additional umodes to apply to the default_umodes upon connect. + auth {} flags ~~~~~~~~~~~~~ diff --git a/include/s_conf.h b/include/s_conf.h index ce5d9388..4d4b6b40 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -72,6 +72,7 @@ struct ConfItem char *className; /* Name of class */ struct Class *c_class; /* Class of connection */ rb_patricia_node_t *pnode; /* Our patricia node */ + int umodes, umodes_mask; /* Override umodes specified by mask */ }; #define CONF_ILLEGAL 0x80000000 diff --git a/ircd/newconf.c b/ircd/newconf.c index 22cc983b..d6eef9f0 100644 --- a/ircd/newconf.c +++ b/ircd/newconf.c @@ -438,6 +438,53 @@ set_modes_from_table(int *modes, const char *whatis, struct mode_table *tab, con } } +static void +parse_umodes(const char *pm, int *values, int *mask) +{ + int what = MODE_ADD, flag; + + *values = 0; + + if (NULL != mask) + *mask = 0; + + for (; *pm; pm++) + { + switch (*pm) + { + case '+': + what = MODE_ADD; + break; + case '-': + what = MODE_DEL; + break; + + /* don't allow +o */ + case 'o': + case 'S': + case 'Z': + case ' ': + break; + + default: + flag = user_modes[(unsigned char) *pm]; + if (flag) + { + /* Proper value has probably not yet been set + * so don't check oper_only_umodes -- jilles */ + if (what == MODE_ADD) + *values |= flag; + else + *values &= ~flag; + + if (NULL != mask) + *mask |= flag; + } + break; + } + } +} + static void conf_set_privset_extends(void *data) { @@ -1157,6 +1204,14 @@ conf_set_auth_class(void *data) yy_aconf->className = rb_strdup(data); } +static void +conf_set_auth_umodes(void *data) +{ + char *umodes = data; + + parse_umodes(umodes, &yy_aconf->umodes, &yy_aconf->umodes_mask); +} + static int conf_begin_connect(struct TopConf *tc) { @@ -1546,41 +1601,9 @@ conf_set_general_compression_level(void *data) static void conf_set_general_default_umodes(void *data) { - char *pm; - int what = MODE_ADD, flag; + char *umodes = data; - ConfigFileEntry.default_umodes = 0; - for (pm = (char *) data; *pm; pm++) - { - switch (*pm) - { - case '+': - what = MODE_ADD; - break; - case '-': - what = MODE_DEL; - break; - - /* don't allow +o */ - case 'o': - case 'S': - case 'Z': - case ' ': - break; - - default: - if ((flag = user_modes[(unsigned char) *pm])) - { - /* Proper value has probably not yet been set - * so don't check oper_only_umodes -- jilles */ - if (what == MODE_ADD) - ConfigFileEntry.default_umodes |= flag; - else - ConfigFileEntry.default_umodes &= ~flag; - } - break; - } - } + parse_umodes(umodes, &ConfigFileEntry.default_umodes, NULL); } static void @@ -2607,6 +2630,7 @@ static struct ConfEntry conf_auth_table[] = { "redirserv", CF_QSTRING, conf_set_auth_redir_serv, 0, NULL }, { "redirport", CF_INT, conf_set_auth_redir_port, 0, NULL }, { "flags", CF_STRING | CF_FLIST, conf_set_auth_flags, 0, NULL }, + { "umodes", CF_QSTRING, conf_set_auth_umodes, 0, NULL}, { "\0", 0, NULL, 0, NULL } }; diff --git a/ircd/s_user.c b/ircd/s_user.c index afd37d99..b2c75bc7 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -351,7 +351,7 @@ register_local_user(struct Client *client_p, struct Client *source_p) char tmpstr2[BUFSIZE]; char ipaddr[HOSTIPLEN]; char myusername[USERLEN+1]; - int status; + int status, umodes; s_assert(NULL != source_p); s_assert(MyConnect(source_p)); @@ -594,7 +594,11 @@ register_local_user(struct Client *client_p, struct Client *source_p) SetDynSpoof(source_p); } - source_p->umodes |= ConfigFileEntry.default_umodes & ~ConfigFileEntry.oper_only_umodes & ~orphaned_umodes; + umodes = ConfigFileEntry.default_umodes & ~aconf->umodes_mask; + umodes |= aconf->umodes; + umodes &= ~ConfigFileEntry.oper_only_umodes; + umodes &= ~orphaned_umodes; + source_p->umodes |= umodes; call_hook(h_new_local_user, source_p);