+2002-04-05 Andrew Miller <a1kmm@mware.virtualave.net>
+ * 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 <vampire@p16.pub.ro>
* include/channel.h: fix compiler warnings (paratheses around &&)
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 */
#include <netinet/in.h> /* struct in_addr */
#define INCLUDED_netinet_in_h
#endif
+#include "client.h"
struct Client;
struct SLink;
* 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 {
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 */
}
}
-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 {
*/
%{
-extern int conf_fd, lineno;
#include <unistd.h>
+#include <stdio.h>
+#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]+
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];
%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 <num> sizespec
%type <num> timespec, timefactor, factoredtimes, factoredtime
-%type <num> expr
+%type <num> expr, yesorno, privtype
%left '+' '-'
%left '*' '/'
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 ';'
{
* 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;
};
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;
stringlist: QSTRING
{
stringlist[0] = $1;
- stringno = 1;
+ stringlist[1] = $1;
+ stringno = 2;
} posextrastrings
{
feature_set(NULL, (const char * const *)stringlist, stringno);
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);
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <stdio.h>
#ifndef INADDR_NONE
#define INADDR_NONE 0xffffffff
#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;
}
}
}
}
- client_set_privs(new_client); /* set privs on user */
+ client_set_privs(new_client, NULL); /* set privs on user */
/*
* Set new nick name.
*/
*/
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;