diff --git a/conf/confbase.Y b/conf/confbase.Y
index 4bf70ccf..cdbdf1ce 100644
--- a/conf/confbase.Y
+++ b/conf/confbase.Y
@@ -100,7 +100,6 @@ CF_DECLS
mpls_label_stack *mls;
const struct adata *bs;
struct aggr_item_node *ai;
- struct cli_config *cli;
}
%token END CLI_MARKER INVALID_TOKEN ELSECOL DDOT
diff --git a/doc/bird.sgml b/doc/bird.sgml
index 14cdc9c9..3df17039 100644
--- a/doc/bird.sgml
+++ b/doc/bird.sgml
@@ -1253,6 +1253,11 @@ socket multiple times and BIRD may behave weirdly if this happens. On shutdown,
the additional sockets get removed immediately and only the main socket stays
until the very end.
+
The remote control socket can be also set as restricted by
+Usage
diff --git a/nest/cli.c b/nest/cli.c
index b54a0d76..eed99414 100644
--- a/nest/cli.c
+++ b/nest/cli.c
@@ -306,7 +306,7 @@ cli_event(void *data)
}
cli *
-cli_new(void *priv)
+cli_new(void *priv, struct cli_config *cf)
{
pool *p = rp_new(cli_pool, "CLI");
cli *c = mb_alloc(p, sizeof(cli));
@@ -321,6 +321,12 @@ cli_new(void *priv)
c->parser_pool = lp_new_default(c->pool);
c->show_pool = lp_new_default(c->pool);
c->rx_buf = mb_alloc(c->pool, CLI_RX_BUF_SIZE);
+
+ c->config = cf;
+ config_add_obstacle(cf->config);
+ if (cf->restricted)
+ c->restricted = 1;
+
ev_schedule(c->event);
return c;
}
@@ -413,6 +419,7 @@ cli_free(cli *c)
c->cleanup(c);
if (c == cmd_reconfig_stored_cli)
cmd_reconfig_stored_cli = NULL;
+ config_del_obstacle(c->config->config);
rfree(c->pool);
}
diff --git a/nest/cli.h b/nest/cli.h
index c20f9c47..f3c43167 100644
--- a/nest/cli.h
+++ b/nest/cli.h
@@ -29,6 +29,7 @@ struct cli_out {
typedef struct cli {
node n; /* Node in list of all log hooks */
+ struct cli_config *config; /* Configuration of the appropriate cli */
pool *pool;
void *priv; /* Private to sysdep layer */
byte *rx_buf, *rx_pos; /* sysdep */
@@ -60,6 +61,7 @@ struct cli_config {
const char *name;
struct config *config;
uint uid, gid, mode;
+ _Bool restricted;
};
#include "lib/tlists.h"
@@ -81,7 +83,7 @@ static inline void cli_separator(cli *c)
/* Functions provided to sysdep layer */
-cli *cli_new(void *);
+cli *cli_new(void *, struct cli_config *);
void cli_init(void);
void cli_free(cli *);
void cli_kick(cli *);
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index 665b0b09..7607f34a 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -14,6 +14,7 @@ CF_HDR
CF_DEFINES
static struct log_config *this_log;
+static struct cli_config *this_cli_config;
CF_DECLS
@@ -21,7 +22,6 @@ CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT, CLI)
CF_KEYWORDS(ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG)
CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT, THREADS)
-%type cli_opts
%type log_mask log_mask_list log_cat cfg_timeout
%type cfg_name
%type timeformat_which
@@ -127,18 +127,26 @@ mrtdump_base:
conf: cli ;
cli: CLI text cli_opts {
- $3->name = $2;
- cli_config_add_tail(&new_config->cli, $3);
+ this_cli_config->name = $2;
+ cli_config_add_tail(&new_config->cli, this_cli_config);
+ this_cli_config = NULL;
} ;
-cli_opts: ';' {
- $$ = cfg_alloc(sizeof *$$);
- *$$ = (typeof (*$$)) {
+cli_opts: cli_opts_begin '{' cli_opts_block '}' ';' | cli_opts_begin ';' ;
+
+cli_opts_begin: {
+ this_cli_config = cfg_alloc(sizeof *this_cli_config);
+ *this_cli_config = (typeof (*this_cli_config)) {
.config = new_config,
.mode = 0660,
};
};
+cli_opts_block:
+ /* EMPTY */ |
+ cli_opts_block RESTRICT { this_cli_config->restricted = 1; }
+;
+
conf: debug_unix ;
debug_unix:
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index 17f7edb5..880cc3c4 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -538,7 +538,7 @@ cli_connect(sock *s, uint size UNUSED)
s->rx_hook = cli_rx;
s->tx_hook = cli_tx;
s->err_hook = cli_err;
- s->data = c = cli_new(s);
+ s->data = c = cli_new(s, ((struct cli_listener *) s->data)->config);
s->pool = c->pool; /* We need to have all the socket buffers allocated in the cli pool */
s->fast_rx = 1;
c->rx_pos = c->rx_buf;
@@ -555,7 +555,7 @@ cli_listen(struct cli_config *cf)
s->type = SK_UNIX_PASSIVE;
s->rx_hook = cli_connect;
s->err_hook = cli_connect_err;
- s->data = cf;
+ s->data = l;
s->rbsize = 1024;
s->fast_rx = 1;