From f201a4605fb3c20f6bb5bc32034b35a1855591b7 Mon Sep 17 00:00:00 2001 From: Michael Poole Date: Sun, 18 Mar 2007 01:46:59 +0000 Subject: [PATCH] Allow multiple host entries in Operator and Motd blocks. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/branches/u2_10_12_branch@1782 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- ChangeLog | 17 ++++++++++++ doc/example.conf | 9 +++++++ ircd/ircd_parser.y | 65 ++++++++++++++++++++++++++++++---------------- ircd/s_conf.c | 1 - 4 files changed, 69 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 034218d..b931b81 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2007-03-17 Michael Poole + + * doc/example.conf (Operator): Update documentation to mention + more than one host entry is allowed. + (Motd): Likewise. + + * ircd/ircd_parser.y (hosts): New file-scope variable. + (free_slist): New helper function. + (operblock): Iterate over hosts instead of using the single host. + (operhost): Prepend the mask to hosts. + (motdblock): Iterate over hosts instead of using the single host. + (motdhost): Prepend the mask to hosts. + (motdfile): Fix possible leak of "pass" string (the filename). + + * ircd/s_conf.c (conf_parse_userhost): Stop freeing the host + string; operblock (the only caller) frees it now. + 2007-03-17 Michael Poole * ircd/list.c (free_link): Only decrement the in-use count of diff --git a/doc/example.conf b/doc/example.conf index ade236e..93ad60e 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -370,6 +370,10 @@ Client { # file = "path/to/motd/file"; # }; # +# More than one host = "mask"; entry may be present in one block; this +# has the same effect as one Motd block for each host entry, but makes +# it easier to update the messages's filename. +# # DPATH/net_com.motd contains a special MOTD where users are encouraged # to register their domains and get their own client{} lines if they're in # Europe, or move to US.UnderNet.org if they're in the USA. @@ -608,6 +612,11 @@ CRULE # is not not passed along to other servers. On Undernet, this prevents # them from using Uworld as well. # +# More than one host = "mask"; entry may be present in one block; this +# has the same effect as one Operator block for each host entry, but +# makes it easier to update operator nicks, passwords, classes, and +# privileges. +# # Operator { # host = "host/IP mask"; # name = "opername"; diff --git a/ircd/ircd_parser.y b/ircd/ircd_parser.y index 29b14ef..dc815f9 100644 --- a/ircd/ircd_parser.y +++ b/ircd/ircd_parser.y @@ -74,6 +74,7 @@ /* Now all the globals we need :/... */ int tping, tconn, maxlinks, sendq, port, invert, stringno, flags; char *name, *pass, *host, *ip, *username, *origin, *hub_limit; + struct SLink *hosts; char *stringlist[MAX_STRINGS]; struct ListenerFlags listen_flags; struct ConnectionClass *c_class; @@ -92,6 +93,16 @@ static void parse_error(char *pattern,...) { yyerror(error_buffer); } +static void free_slist(struct SLink **link) { + struct SLink *next; + while (*link != NULL) { + next = (*link)->next; + MyFree((*link)->value.cp); + free_link(*link); + *link = next; + } +} + %} %token QSTRING @@ -560,33 +571,33 @@ uworldname: NAME '=' QSTRING ';' operblock: OPER '{' operitems '}' ';' { struct ConfItem *aconf = NULL; + struct SLink *link; + if (name == NULL) parse_error("Missing name in operator block"); else if (pass == NULL) parse_error("Missing password in operator block"); /* Do not check password length because it may be crypted. */ - else if (host == NULL) - parse_error("Missing host in operator block"); + else if (hosts == NULL) + parse_error("Missing host(s) in operator block"); else if (c_class == NULL) parse_error("Invalid or missing class in operator block"); else if (!FlagHas(&privs_dirty, PRIV_PROPAGATE) && !FlagHas(&c_class->privs_dirty, PRIV_PROPAGATE)) parse_error("Operator block for %s and class %s have no LOCAL setting", name, c_class->cc_name); - else { + else for (link = hosts; link != NULL; link = link->next) { aconf = make_conf(CONF_OPERATOR); - aconf->name = name; - aconf->passwd = pass; - conf_parse_userhost(aconf, host); + DupString(aconf->name, name); + DupString(aconf->passwd, pass); + conf_parse_userhost(aconf, link->value.cp); aconf->conn_class = c_class; memcpy(&aconf->privs, &privs, sizeof(aconf->privs)); memcpy(&aconf->privs_dirty, &privs_dirty, sizeof(aconf->privs_dirty)); } - if (!aconf) { - MyFree(name); - MyFree(pass); - MyFree(host); - } - name = pass = host = NULL; + MyFree(name); + MyFree(pass); + free_slist(&hosts); + name = pass = NULL; c_class = NULL; memset(&privs, 0, sizeof(privs)); memset(&privs_dirty, 0, sizeof(privs_dirty)); @@ -605,16 +616,19 @@ operpass: PASS '=' QSTRING ';' }; operhost: HOST '=' QSTRING ';' { - MyFree(host); + struct SLink *link; + link = make_link(); if (!strchr($3, '@')) { int uh_len; - host = (char*) MyMalloc((uh_len = strlen($3)+3)); - ircd_snprintf(0, host, uh_len, "*@%s", $3); - MyFree($3); + link->value.cp = (char*) MyMalloc((uh_len = strlen($3)+3)); + ircd_snprintf(0, link->value.cp, uh_len, "*@%s", $3); } else - host = $3; + DupString(link->value.cp, $3); + MyFree($3); + link->next = hosts; + hosts = link; }; operclass: CLASS '=' QSTRING ';' { @@ -968,22 +982,29 @@ cruleall: ALL '=' YES ';' motdblock: MOTD '{' motditems '}' ';' { - if (host != NULL && pass != NULL) - motd_add(host, pass); - MyFree(host); + struct SLink *link; + if (pass != NULL) + for (link = hosts; link != NULL; link = link->next) + motd_add(link->value.cp, pass); + free_slist(&hosts); MyFree(pass); - host = pass = NULL; + pass = NULL; }; motditems: motditem motditems | motditem; motditem: motdhost | motdfile; motdhost: HOST '=' QSTRING ';' { - host = $3; + struct SLink *link; + link = make_link(); + link->value.cp = $3; + link->next = hosts; + hosts = link; }; motdfile: TFILE '=' QSTRING ';' { + MyFree(pass); pass = $3; }; diff --git a/ircd/s_conf.c b/ircd/s_conf.c index 2cc9385..18f4b00 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -221,7 +221,6 @@ void conf_parse_userhost(struct ConfItem *aconf, char *host) aconf->addrbits = addrbits; else aconf->addrbits = -1; - MyFree(host); } /** Copies a completed DNS query into its ConfItem. -- 2.20.1