From: Andrew Miller Date: Fri, 5 Apr 2002 11:36:59 +0000 (+0000) Subject: Author: Andrew Miller X-Git-Url: http://git.pk910.de/?a=commitdiff_plain;h=8eae69f6e33691a5bb0c54ef8b64c4e653459c47;p=ircu2.10.12-pk.git Author: Andrew Miller Log message: - Allowed specification of the priviledge flags in the config file. - Fixed a bug in the parser so rehash now works properly. To do: - Add documentation to example.conf for the new options. - Sort out features they still don't seem to work properly. git-svn-id: file:///home/klmitch/undernet-ircu/undernet-ircu-svn/ircu2/trunk@715 c9e4aea6-c8fd-4c43-8297-357d70d61c8c --- diff --git a/ChangeLog b/ChangeLog index 0ab716d..067ba7d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-04-05 Andrew Miller + * ircd/s_conf.c, ircd_parser.y, ircd_lexer.l: Add privilege + specification. + * Fix a minor parser bug that meant rehash didn't always + work correctly. + 2002-04-03 Alex Badea * include/channel.h: fix compiler warnings (paratheses around &&) diff --git a/include/client.h b/include/client.h index ffbaf54..3522c40 100644 --- a/include/client.h +++ b/include/client.h @@ -515,7 +515,7 @@ extern int client_get_ping(const struct Client* local_client); 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 void client_set_privs(struct Client *client, struct ConfItem *oper); extern int client_report_privs(struct Client* to, struct Client* client); #endif /* INCLUDED_client_h */ diff --git a/include/s_conf.h b/include/s_conf.h index 6a89ab9..14f6df6 100644 --- a/include/s_conf.h +++ b/include/s_conf.h @@ -17,6 +17,7 @@ #include /* struct in_addr */ #define INCLUDED_netinet_in_h #endif +#include "client.h" struct Client; struct SLink; @@ -50,19 +51,21 @@ struct TRecord; * Structures */ -struct ConfItem { - struct ConfItem* next; - unsigned int status; /* If CONF_ILLEGAL, delete when no clients */ - unsigned int clients; /* Number of *LOCAL* clients using this */ - struct ConnectionClass* conn_class; /* Class of connection */ - struct in_addr ipnum; /* ip number of host field */ - char* host; - char* passwd; - char* name; - time_t hold; /* Hold until this time (calendar time) */ - int dns_pending; /* a dns request is pending */ - unsigned short port; - char bits; /* Number of bits for ipkills */ +struct ConfItem +{ + struct ConfItem *next; + unsigned int status; /* If CONF_ILLEGAL, delete when no clients */ + unsigned int clients; /* Number of *LOCAL* clients using this */ + struct ConnectionClass *conn_class; /* Class of connection */ + struct in_addr ipnum; /* ip number of host field */ + char *host; + char *passwd; + char *name; + time_t hold; /* Hold until this time (calendar time) */ + int dns_pending; /* a dns request is pending */ + unsigned short port; + unsigned char bits; /* Number of bits for ipkills. */ + struct Privs privs; /* Priviledges for opers. */ }; struct ServerConf { @@ -190,6 +193,8 @@ extern int find_kill(struct Client *cptr); extern int find_restrict(struct Client *cptr); extern struct MotdItem* read_motd(const char* motdfile); +extern void set_initial_oper_privs(struct ConfItem *oper, int flags); + extern void yyerror(const char *msg); #endif /* INCLUDED_s_conf_h */ diff --git a/ircd/client.c b/ircd/client.c index c313d78..fc4dd9c 100644 --- a/ircd/client.c +++ b/ircd/client.c @@ -101,121 +101,121 @@ void client_add_sendq(struct Connection* con, struct Connection** con_p) } } -static struct { +static struct +{ unsigned int priv; enum Feature feat; unsigned int flag; -} feattab[] = { - { PRIV_WHOX, FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_DISPLAY, FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_CHAN_LIMIT, FEAT_OPER_NO_CHAN_LIMIT, (FLAGS_OPER | FLAGS_LOCOP) }, - { PRIV_MODE_LCHAN, FEAT_OPER_MODE_LCHAN, (FLAGS_OPER | FLAGS_LOCOP) }, - { 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_LIST_CHAN, FEAT_LIST_CHAN, (FLAGS_OPER | FLAGS_LOCOP) }, - - { PRIV_KILL, FEAT_LOCAL_KILL_ONLY, 0 }, - { PRIV_GLINE, FEAT_CONFIG_OPERCMDS, ~0 }, - { PRIV_JUPE, FEAT_CONFIG_OPERCMDS, ~0 }, - { PRIV_OPMODE, FEAT_CONFIG_OPERCMDS, ~0 }, - { PRIV_BADCHAN, FEAT_CONFIG_OPERCMDS, ~0 }, - - { PRIV_PROPAGATE, FEAT_LAST_F, FLAGS_OPER }, - { PRIV_SEE_OPERS, FEAT_LAST_F, FLAGS_OPER }, - { PRIV_KILL, FEAT_OPER_KILL, FLAGS_OPER }, - { 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_WIDE_GLINE, FEAT_OPER_WIDE_GLINE, FLAGS_OPER }, - { PRIV_LIST_CHAN, FEAT_OPER_LIST_CHAN, FLAGS_OPER }, +} feattab[] = + { + { PRIV_WHOX, FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_DISPLAY, FEAT_LAST_F, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_CHAN_LIMIT, FEAT_OPER_NO_CHAN_LIMIT, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_MODE_LCHAN, FEAT_OPER_MODE_LCHAN, (FLAGS_OPER | FLAGS_LOCOP) }, + { 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_LIST_CHAN, FEAT_LIST_CHAN, (FLAGS_OPER | FLAGS_LOCOP) }, + { PRIV_KILL, FEAT_LOCAL_KILL_ONLY, 0 }, + { PRIV_GLINE, FEAT_CONFIG_OPERCMDS, ~0 }, + { PRIV_JUPE, FEAT_CONFIG_OPERCMDS, ~0 }, + { PRIV_OPMODE, FEAT_CONFIG_OPERCMDS, ~0 }, + { PRIV_BADCHAN, FEAT_CONFIG_OPERCMDS, ~0 }, + { PRIV_PROPAGATE, FEAT_LAST_F, FLAGS_OPER }, + { PRIV_SEE_OPERS, FEAT_LAST_F, FLAGS_OPER }, + { PRIV_KILL, FEAT_OPER_KILL, FLAGS_OPER }, + { 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_WIDE_GLINE, FEAT_OPER_WIDE_GLINE, FLAGS_OPER }, + { PRIV_LIST_CHAN, FEAT_OPER_LIST_CHAN, 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 }, + { PRIV_WIDE_GLINE, FEAT_LOCOP_WIDE_GLINE, FLAGS_LOCOP }, + { PRIV_LIST_CHAN, FEAT_LOCOP_LIST_CHAN, FLAGS_LOCOP }, + { 0, FEAT_LAST_F, 0 } + }; - { 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 }, - { PRIV_WIDE_GLINE, FEAT_LOCOP_WIDE_GLINE, FLAGS_LOCOP }, - { PRIV_LIST_CHAN, FEAT_LOCOP_LIST_CHAN, FLAGS_LOCOP }, - { 0, FEAT_LAST_F, 0 } -}; +void +set_initial_oper_privs(struct ConfItem *oper, int flags) +{ + int i; + memset(&oper->privs, 0, sizeof(oper->privs)); + for (i = 0; feattab[i].priv; i++) + if ((feattab[i].flag | flags) != 0 && feattab[i].flag != ~0) + PrivSet(&oper->privs, feattab[i].priv); +} /* client_set_privs(struct Client* client) * * Sets the privileges for opers. */ void -client_set_privs(struct Client* client) +client_set_privs(struct Client *client, struct ConfItem *oper) { - struct Privs privs; - struct Privs antiprivs; int i; - memset(&privs, 0, sizeof(struct Privs)); - memset(&antiprivs, 0, sizeof(struct Privs)); + memset(&(cli_privs(client)), 0, sizeof(struct Privs)); - if (!IsAnOper(client)) { /* clear privilege mask */ - memset(&(cli_privs(client)), 0, sizeof(struct Privs)); + if (!IsAnOper(client)) return; - } else if (!MyConnect(client)) { + else if (!MyConnect(client)) + { memset(&(cli_privs(client)), 255, sizeof(struct Privs)); PrivClr(&(cli_privs(client)), PRIV_SET); return; } + else if (oper == NULL) + return; - /* This sequence is temporary until the .conf is carefully rewritten */ + /* Copy across privs from the config. */ + cli_privs(client) = oper->privs; - for (i = 0; feattab[i].priv; i++) { - if (feattab[i].flag == 0) { - if (feature_bool(feattab[i].feat)) - PrivSet(&antiprivs, feattab[i].priv); - } else if (feattab[i].flag == ~0) { - if (!feature_bool(feattab[i].feat)) - PrivSet(&antiprivs, feattab[i].priv); - } else if (cli_flags(client) & feattab[i].flag) { - if (feattab[i].feat == FEAT_LAST_F || - feature_bool(feattab[i].feat)) - PrivSet(&privs, feattab[i].priv); - } - } + /* Remove privileges disallowed by features... */ + for (i = 0; feattab[i].priv; i++) + if (feattab[i].flag == 0 && feature_bool(feattab[i].feat)) + PrivClr(&cli_privs(client), feattab[i].priv); + else if (feattab[i].flag == ~0 && !feature_bool(feattab[i].feat)) + PrivClr(&cli_privs(client), feattab[i].priv); - /* This is the end of the gross section */ - - if (PrivHas(&privs, PRIV_PROPAGATE)) - PrivSet(&privs, PRIV_DISPLAY); /* force propagating opers to display */ - else { /* if they don't propagate oper status, prevent desyncs */ - PrivSet(&antiprivs, PRIV_KILL); - PrivSet(&antiprivs, PRIV_GLINE); - PrivSet(&antiprivs, PRIV_JUPE); - PrivSet(&antiprivs, PRIV_OPMODE); - PrivSet(&antiprivs, PRIV_BADCHAN); + /* This should be handled in the config, but lets be sure... */ + if (PrivHas(&cli_privs(client), PRIV_PROPAGATE)) + /* force propagating opers to display */ + PrivSet(&cli_privs(client), PRIV_DISPLAY); + else + { + /* if they don't propagate oper status, prevent desyncs */ + PrivClr(&cli_privs(client), PRIV_KILL); + PrivClr(&cli_privs(client), PRIV_GLINE); + PrivClr(&cli_privs(client), PRIV_JUPE); + PrivClr(&cli_privs(client), PRIV_OPMODE); + PrivClr(&cli_privs(client), PRIV_BADCHAN); } - - for (i = 0; i <= _PRIV_IDX(PRIV_LAST_PRIV); i++) - privs.priv_mask[i] &= ~antiprivs.priv_mask[i]; - - cli_privs(client) = privs; } static struct { diff --git a/ircd/ircd_lexer.l b/ircd/ircd_lexer.l index ea9ccb8..f3d893b 100644 --- a/ircd/ircd_lexer.l +++ b/ircd/ircd_lexer.l @@ -21,19 +21,29 @@ */ %{ -extern int conf_fd, lineno; #include +#include +#include "ircd.h" #include "y.tab.h" -#undef YY_INPUT -/* Just stop the lexer at EOF or error. */ -#define YY_INPUT(buf,result,max_size) \ - if ((result = read(conf_fd, buf, max_size)) <= 0) \ - result = 0; + +extern int lineno; + +void +init_lexer(void) +{ + yyin = fopen(configfile, "r"); + if (yyin == NULL) + yy_fatal_error("Could not open the configuration file."); + YY_NEW_FILE; + lineno = 1; +} + %} %option noyywrap %option case-insensitive %option nounput + WHITE [ \t\r]+ SHCOMMENT #[^\n]* NUMBER [0-9]+ @@ -111,5 +121,31 @@ ip return IP; crule return CRULE; kill return KILL; features return FEATURES; +bypass_local_channel_limits return TPRIV_CHAN_LIMIT; +set_local_channel_modes return TPRIV_MODE_LCHAN; +protected_local_channel return TPRIV_DEOP_LCHAN; +bypass_join_local_channels return TPRIV_WALK_LCHAN; +global_kill return TPRIV_KILL; +local_kill return TPRIV_LOCAL_KILL; +rehash return TPRIV_REHASH; +restart return TPRIV_RESTART; +die return TPRIV_DIE; +gline return TPRIV_GLINE; +local_gline return TPRIV_LOCAL_GLINE; +jupe_server return TPRIV_JUPE; +local_jupe_server return TPRIV_LOCAL_JUPE; +hack_channel_modes return TPRIV_OPMODE; +change_settings return TPRIV_SET; +extended_who_information return TPRIV_WHOX; +gline_channels return TPRIV_BADCHAN; +local_gline_channels return TPRIV_LOCAL_BADCHAN; +see_private_channels return TPRIV_SEE_CHAN; +see_invisible_users return TPRIV_SHOW_INVIS; +list_all_invisible_users return TPRIV_SHOW_ALL_INVIS; +globally_opered return TPRIV_PROPAGATE; +unlimited_who_queries return TPRIV_UNLIMIT_QUERY; +oper_status_display return TPRIV_DISPLAY; +see_other_opers return TPRIV_SEE_OPERS; +wide_glines return TPRIV_WIDE_GLINE; \n lineno++; . return yytext[0]; diff --git a/ircd/ircd_parser.y b/ircd/ircd_parser.y index d49ab33..81a15fe 100644 --- a/ircd/ircd_parser.y +++ b/ircd/ircd_parser.y @@ -133,9 +133,18 @@ %token ALL %token IP %token FEATURES +/* and now a lot of priviledges... */ +%token TPRIV_CHAN_LIMIT, TPRIV_MODE_LCHAN, TPRIV_DEOP_LCHAN, TPRIV_WALK_LCHAN +%token TPRIV_KILL, TPRIV_LOCAL_KILL, TPRIV_REHASH, TPRIV_RESTART, TPRIV_DIE +%token TPRIV_GLINE, TPRIV_LOCAL_GLINE, TPRIV_JUPE, TPRIV_LOCAL_JUPE +%token TPRIV_LOCAL_OPMODE, TPRIV_OPMODE, TPRIV_SET, TPRIV_WHOX, TPRIV_BADCHAN +%token TPRIV_LOCAL_BADCHAN +%token TPRIV_SEE_CHAN, TPRIV_SHOW_INVIS, TPRIV_SHOW_ALL_INVIS, TPRIV_PROPAGATE +%token TPRIV_UNLIMIT_QUERY, TPRIV_DISPLAY, TPRIV_SEE_OPERS, TPRIV_WIDE_GLINE +/* and some types... */ %type sizespec %type timespec, timefactor, factoredtimes, factoredtime -%type expr +%type expr, yesorno, privtype %left '+' '-' %left '*' '/' @@ -459,24 +468,27 @@ operblock: OPER aconf = MyMalloc(sizeof(*aconf)); memset(aconf, 0, sizeof(*aconf)); aconf->status = CONF_OPERATOR; + set_initial_oper_privs(aconf, (FLAGS_OPER | FLAGS_LOCOP)); } '{' operitems '}' ';' { if (aconf->name != NULL && aconf->passwd != NULL && aconf->host != NULL) { - aconf->next = GlobalConfList; - GlobalConfList = aconf; + log_write(LS_CONFIG, L_ERROR, 0, "added an oper block for host %s", aconf->host); + aconf->next = GlobalConfList; + GlobalConfList = aconf; } else { - MyFree(aconf->name); - MyFree(aconf->passwd); - MyFree(aconf->host); - MyFree(aconf); - aconf = NULL; + log_write(LS_CONFIG, L_ERROR, 0, "operator blocks need a name, password, and host."); + MyFree(aconf->name); + MyFree(aconf->passwd); + MyFree(aconf->host); + MyFree(aconf); + aconf = NULL; } }; operitems: operitem | operitems operitem; -operitem: opername | operpass | operlocal | operhost | operclass; +operitem: opername | operpass | operlocal | operhost | operclass | operpriv; opername: NAME '=' QSTRING ';' { @@ -496,8 +508,12 @@ operlocal: LOCAL '=' YES ';' * permission values here. But for now, I am just going with local * opers... */ aconf->status = CONF_LOCOP; + /* XXX blow away existing priviledges. */ + set_initial_oper_privs(aconf, FLAGS_LOCOP); } | LOCAL '=' NO ';' { + /* XXX blow away existing priviledges. */ + set_initial_oper_privs(aconf, (FLAGS_OPER|FLAGS_LOCOP)); aconf->status = CONF_OPERATOR; }; @@ -520,6 +536,44 @@ operclass: CLASS '=' QSTRING ';' aconf->conn_class = find_class(yylval.text); }; +operpriv: privtype '=' yesorno ';' +{ + if ($3 == 1) + PrivSet(&aconf->privs, $1); + else + PrivClr(&aconf->privs, $1); +}; + +privtype: TPRIV_CHAN_LIMIT { $$ = PRIV_CHAN_LIMIT; } | + TPRIV_MODE_LCHAN { $$ = PRIV_MODE_LCHAN; } | + TPRIV_DEOP_LCHAN { $$ = PRIV_DEOP_LCHAN; } | + TPRIV_WALK_LCHAN { $$ = PRIV_WALK_LCHAN; } | + TPRIV_KILL { $$ = PRIV_KILL; } | + TPRIV_LOCAL_KILL { $$ = PRIV_LOCAL_KILL; } | + TPRIV_REHASH { $$ = PRIV_REHASH; } | + TPRIV_RESTART { $$ = PRIV_RESTART; } | + TPRIV_DIE { $$ = PRIV_DIE; } | + TPRIV_GLINE { $$ = PRIV_GLINE; } | + TPRIV_LOCAL_GLINE { $$ = PRIV_LOCAL_GLINE; } | + TPRIV_JUPE { $$ = PRIV_JUPE; } | + TPRIV_LOCAL_JUPE { $$ = PRIV_LOCAL_JUPE; } | + TPRIV_LOCAL_OPMODE { $$ = PRIV_LOCAL_OPMODE; } | + TPRIV_OPMODE { $$ = PRIV_OPMODE; }| + TPRIV_SET { $$ = PRIV_SET; } | + TPRIV_WHOX { $$ = PRIV_WHOX; } | + TPRIV_BADCHAN { $$ = PRIV_BADCHAN; } | + TPRIV_LOCAL_BADCHAN { $$ = TPRIV_LOCAL_BADCHAN; } | + TPRIV_SEE_CHAN { $$ = PRIV_SEE_CHAN; } | + TPRIV_SHOW_INVIS { $$ = PRIV_SHOW_INVIS; } | + TPRIV_SHOW_ALL_INVIS { $$ = PRIV_SHOW_ALL_INVIS; } | + TPRIV_PROPAGATE { $$ = PRIV_PROPAGATE; } | + TPRIV_UNLIMIT_QUERY { $$ = PRIV_UNLIMIT_QUERY; } | + TPRIV_DISPLAY { $$ = PRIV_DISPLAY; } | + TPRIV_SEE_OPERS { $$ = PRIV_SEE_OPERS; } | + TPRIV_WIDE_GLINE { $$ = PRIV_WIDE_GLINE; }; + +yesorno: YES { $$ = 1; } | NO { $$ = 0; }; + /* The port block... */ portblock: PORT { port = 0; @@ -797,7 +851,8 @@ featureitem: QSTRING stringlist: QSTRING { stringlist[0] = $1; - stringno = 1; + stringlist[1] = $1; + stringno = 2; } posextrastrings { feature_set(NULL, (const char * const *)stringlist, stringno); diff --git a/ircd/m_oper.c b/ircd/m_oper.c index 767b52d..1166840 100644 --- a/ircd/m_oper.c +++ b/ircd/m_oper.c @@ -179,7 +179,7 @@ int m_oper(struct Client* cptr, struct Client* sptr, int parc, char* parv[]) cli_flags(sptr) |= (FLAGS_WALLOP | FLAGS_SERVNOTICE | FLAGS_DEBUG); set_snomask(sptr, SNO_OPERDEFAULT, SNO_ADD); - client_set_privs(sptr); + client_set_privs(sptr, aconf); cli_max_sendq(sptr) = 0; /* Get the sendq from the oper's class */ send_umode_out(cptr, sptr, old_mode, HasPriv(sptr, PRIV_PROPAGATE)); send_reply(sptr, RPL_YOUREOPER); diff --git a/ircd/s_conf.c b/ircd/s_conf.c index d1677b1..21fa6ac 100644 --- a/ircd/s_conf.c +++ b/ircd/s_conf.c @@ -63,6 +63,7 @@ #include #include #include +#include #ifndef INADDR_NONE #define INADDR_NONE 0xffffffff @@ -932,301 +933,17 @@ const struct DenyConf* conf_get_deny_list(void) #define MAXCONFLINKS 150 +extern FILE *yyin; +void init_lexer(void); + int read_configuration_file(void) { feature_unmark(); /* unmark all features for resetting later */ /* Now just open an fd. The buffering isn't really needed... */ - if ((conf_fd = open(configfile, O_RDONLY)) < 0) - return 0; - lineno = 1; + init_lexer(); yyparse(); - close(conf_fd); -#if 0 - while (fbgets(line, sizeof(line) - 1, file)) { - if ('#' == *line || IsSpace(*line)) - continue; - - if ((src = strchr(line, '\n'))) - *src = '\0'; - - if (':' != line[1]) { - Debug((DEBUG_ERROR, "Bad config line: %s", line)); - sendto_opmask_butone(0, SNO_OLDSNO,"Bad Config line"); - continue; - } - - /* - * do escapes, quoting, comments, and field breakup in place - * in one pass with a poor mans state machine - */ - field_vector[0] = line; - field_count = 1; - quoted = 0; - - for (src = line, dest = line; *src; ) { - switch (*src) { - case '\\': - ++src; - switch (*src) { - case 'b': - *dest++ = '\b'; - ++src; - break; - case 'f': - *dest++ = '\f'; - ++src; - break; - case 'n': - *dest++ = '\n'; - ++src; - break; - case 'r': - *dest++ = '\r'; - ++src; - break; - case 't': - *dest++ = '\t'; - ++src; - break; - case 'v': - *dest++ = '\v'; - ++src; - break; - case '\\': - *dest++ = '\\'; - ++src; - break; - case '\0': - break; - default: - *dest++ = *src++; - break; - } - break; - case '"': - if (quoted) - quoted = 0; - else - quoted = 1; - /* - * strip quotes - */ - ++src; - break; - case ':': - if (quoted) - *dest++ = *src++; - else { - *dest++ = '\0'; - field_vector[field_count++] = dest; - if (field_count > MAX_FIELDS) - *src = '\0'; - else - ++src; - } - break; - case '#': - *src = '\0'; - break; - default: - *dest++ = *src++; - break; - } - } - *dest = '\0'; - - if (field_count < 2 || EmptyString(field_vector[0])) - continue; - - if (aconf) - free_conf(aconf); - - aconf = make_conf(); - - switch (*field_vector[0]) { - case 'A': /* Name, e-mail address of administrator */ - case 'a': /* of this server. CONF_ADMIN */ - conf_add_admin(field_vector, field_count); - aconf->status = CONF_ILLEGAL; - break; - case 'C': /* Server where I should try to connect */ - case 'c': /* in case of lp failures */ - ++ccount; - aconf->status = CONF_SERVER; - break; - /* Connect rule */ - case 'D': /* CONF_CRULEALL */ - conf_add_crule(field_vector, field_count, CRULE_ALL); - aconf->status = CONF_ILLEGAL; - break; - /* Connect rule - autos only */ - case 'd': /* CONF_CRULEAUTO */ - conf_add_crule(field_vector, field_count, CRULE_AUTO); - aconf->status = CONF_ILLEGAL; - break; - case 'F': /* Feature line */ - case 'f': - feature_set(0, &field_vector[1], field_count - 1); - aconf->status = CONF_ILLEGAL; - break; - case 'H': /* Hub server line */ - case 'h': - aconf->status = CONF_HUB; - break; - case 'I': /* Just plain normal irc client trying */ - case 'i': /* to connect me */ - aconf->status = CONF_CLIENT; - break; - case 'K': /* Kill user line on irc.conf */ - conf_add_deny(field_vector, field_count, 0); - aconf->status = CONF_ILLEGAL; - break; - case 'k': /* Kill user line based on IP in ircd.conf */ - conf_add_deny(field_vector, field_count, 1); - aconf->status = CONF_ILLEGAL; - break; - /* Operator. Line should contain at least */ - /* password and host where connection is */ - case 'L': /* guaranteed leaf server */ - case 'l': - aconf->status = CONF_LEAF; - break; - /* Me. Host field is name used for this host */ - /* and port number is the number of the port */ - case 'M': - case 'm': /* CONF_ME */ - conf_add_local(field_vector, field_count); - aconf->status = CONF_ILLEGAL; - break; - case 'O': - aconf->status = CONF_OPERATOR; - break; - /* Local Operator, (limited privs --SRB) */ - case 'o': - aconf->status = CONF_LOCOP; - break; - case 'P': /* listen port line */ - case 'p': /* CONF_LISTEN_PORT */ - conf_add_listener(field_vector, field_count); - aconf->status = CONF_ILLEGAL; - break; - case 'T': /* print out different motd's */ - case 't': /* based on hostmask - CONF_TLINES */ - motd_add(field_vector[1], field_vector[2]); - aconf->status = CONF_ILLEGAL; - break; - case 'U': /* Underworld server, allowed to hack modes */ - case 'u': /* *Every* server on the net must define the same !!! */ - aconf->status = CONF_UWORLD; - break; - case 'Y': - case 'y': /* CONF_CLASS */ - conf_add_class(field_vector, field_count); - aconf->status = CONF_ILLEGAL; - break; - default: - Debug((DEBUG_ERROR, "Error in config file: %s", line)); - sendto_opmask_butone(0, SNO_OLDSNO, "Unknown prefix in config file: %c", - *field_vector[0]); - aconf->status = CONF_ILLEGAL; - break; - } - if (IsIllegal(aconf)) - continue; - - if (!EmptyString(field_vector[1])) - DupString(aconf->host, field_vector[1]); - - if (!EmptyString(field_vector[2])) - DupString(aconf->passwd, field_vector[2]); - - if (field_count > 3 && !EmptyString(field_vector[3])) - DupString(aconf->name, field_vector[3]); - - if (field_count > 4 && !EmptyString(field_vector[4])) - aconf->port = atoi(field_vector[4]); - - if (field_count > 5 && !EmptyString(field_vector[5])) - aconf->conn_class = find_class(atoi(field_vector[5])); - - /* - * Associate each conf line with a class by using a pointer - * to the correct class record. -avalon - */ - if (aconf->status & CONF_CLIENT_MASK) { - if (aconf->conn_class == 0) - aconf->conn_class = find_class(0); - } - if (aconf->status & CONF_CLIENT) { - struct ConfItem *bconf; - - if ((bconf = find_conf_entry(aconf, aconf->status))) { - delist_conf(bconf); - bconf->status &= ~CONF_ILLEGAL; - if (aconf->status == CONF_CLIENT) { - /* - * copy the password field in case it changed - */ - MyFree(bconf->passwd); - bconf->passwd = aconf->passwd; - aconf->passwd = 0; - - ConfLinks(bconf) -= bconf->clients; - bconf->conn_class = aconf->conn_class; - if (bconf->conn_class) - ConfLinks(bconf) += bconf->clients; - } - free_conf(aconf); - aconf = bconf; - } - } - if (aconf->status & CONF_SERVER) { - if (ccount > MAXCONFLINKS || !aconf->host || strchr(aconf->host, '*') || - strchr(aconf->host, '?') || !aconf->name) - continue; - } - if (aconf->status & (CONF_LOCOP | CONF_OPERATOR)) { - if (!strchr(aconf->host, '@')) { - char* newhost; - int len = 3; /* *@\0 = 3 */ - - len += strlen(aconf->host); - newhost = (char*) MyMalloc(len); - assert(0 != newhost); - ircd_snprintf(0, newhost, len, "*@%s", aconf->host); - MyFree(aconf->host); - aconf->host = newhost; - } - } - if (aconf->status & CONF_SERVER) { - if (EmptyString(aconf->passwd)) - continue; - lookup_confhost(aconf); - } - /* - * Juped nicks are listed in the 'password' field of U:lines, - * the list is comma separated and might be empty and/or contain - * empty elements... the only limit is that it MUST be shorter - * than 512 chars, or they will be cutted out :) - */ - if ((aconf->status == CONF_UWORLD) && (aconf->passwd) && (*aconf->passwd)) - addNickJupes(aconf->passwd); - - collapse(aconf->host); - collapse(aconf->name); - Debug((DEBUG_NOTICE, - "Read Init: (%d) (%s) (%s) (%s) (%u) (%p)", - aconf->status, aconf->host, aconf->passwd, - aconf->name, aconf->port, aconf->conn_class)); - aconf->next = GlobalConfList; - GlobalConfList = aconf; - aconf = NULL; - } - if (aconf) - free_conf(aconf); - fbclose(file); -/* nextping = nextconnect = CurrentTime; */ -#endif + fclose(yyin); + yyin = NULL; feature_mark(); /* reset unmarked features */ return 1; } diff --git a/ircd/s_user.c b/ircd/s_user.c index 467bea6..52d55a8 100644 --- a/ircd/s_user.c +++ b/ircd/s_user.c @@ -690,7 +690,7 @@ int set_nick_name(struct Client* cptr, struct Client* sptr, } } } - client_set_privs(new_client); /* set privs on user */ + client_set_privs(new_client, NULL); /* set privs on user */ /* * Set new nick name. */ @@ -1299,13 +1299,13 @@ int set_user_mode(struct Client *cptr, struct Client *sptr, int parc, char *parv */ if (!(setflags & FLAGS_OPER) && IsOper(sptr)) { /* user now oper */ ++UserStats.opers; - client_set_privs(sptr); /* may set propagate privilege */ + client_set_privs(sptr, NULL); } if (HasPriv(sptr, PRIV_PROPAGATE)) /* remember propagate privilege setting */ prop = 1; if ((setflags & FLAGS_OPER) && !IsOper(sptr)) { /* user no longer oper */ --UserStats.opers; - client_set_privs(sptr); /* will clear propagate privilege */ + client_set_privs(sptr, NULL); /* will clear propagate privilege */ } if ((setflags & FLAGS_INVISIBLE) && !IsInvisible(sptr)) --UserStats.inv_clients;