From 86b286101b1b4eea804b4ffa3e0c47c23a664ed2 Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Wed, 14 Mar 2018 12:11:57 -0400 Subject: [PATCH 1/3] vtysh: add -u/--user flag to run commands without enable Signed-off-by: Lou Berger --- vtysh/vtysh.c | 14 +++++++++++--- vtysh/vtysh_main.c | 22 ++++++++++++++++------ 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index 96a5ea9e36..dca5dafa84 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -305,6 +305,7 @@ static int vtysh_execute_func(const char *line, int pager) int closepager = 0; int tried = 0; int saved_ret, saved_node; + extern int user_mode; /* Split readline string up into the vector. */ vline = cmd_make_strvec(line); @@ -312,6 +313,13 @@ static int vtysh_execute_func(const char *line, int pager) if (vline == NULL) return CMD_SUCCESS; + if (user_mode) { + if (strncmp("en", vector_slot(vline, 0), 2) == 0) { + fprintf(stdout, "%% Command not allowed: enable\n"); + return CMD_WARNING; + } + } + saved_ret = ret = cmd_execute_command(vline, vty, &cmd, 1); saved_node = vty->node; @@ -385,13 +393,13 @@ static int vtysh_execute_func(const char *line, int pager) fprintf(stdout, "Warning...\n"); break; case CMD_ERR_AMBIGUOUS: - fprintf(stdout, "%% Ambiguous command.\n"); + fprintf(stdout, "%% Ambiguous command: %s\n", line); break; case CMD_ERR_NO_MATCH: - fprintf(stdout, "%% Unknown command.\n"); + fprintf(stdout, "%% Unknown command: %s\n", line); break; case CMD_ERR_INCOMPLETE: - fprintf(stdout, "%% Command incomplete.\n"); + fprintf(stdout, "%% Command incomplete: %s\n", line); break; case CMD_SUCCESS_DAEMON: { /* diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index a3d2f95ec1..b5cc1d21d1 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -60,6 +60,9 @@ static char history_file[MAXPATHLEN]; /* Flag for indicate executing child command. */ int execute_flag = 0; +/* Flag to indicate if in user/unprivileged mode. */ +int user_mode = 0; + /* For sigsetjmp() & siglongjmp(). */ static sigjmp_buf jmpbuf; @@ -150,6 +153,7 @@ static void usage(int status) " --vty_socket Override vty socket path\n" " --config_dir Override config directory path\n" "-N --pathspace Insert prefix into config & socket paths\n" + "-u --user Run as an unprivileged user\n" "-w, --writeconfig Write integrated config (frr.conf) and exit\n" "-h, --help Display this help and exit\n\n" "Note that multiple commands may be executed from the command\n" @@ -180,6 +184,7 @@ struct option longopts[] = { {"mark", no_argument, NULL, 'm'}, {"writeconfig", no_argument, NULL, 'w'}, {"pathspace", required_argument, NULL, 'N'}, + {"user", no_argument, NULL, 'u'}, {0}}; /* Read a string, and return a pointer to it. Returns NULL on EOF. */ @@ -318,7 +323,7 @@ int main(int argc, char **argv, char **env) /* Option handling. */ while (1) { - opt = getopt_long(argc, argv, "be:c:d:nf:mEhCwN:", longopts, 0); + opt = getopt_long(argc, argv, "be:c:d:nf:mEhCwN:u", longopts, 0); if (opt == EOF) break; @@ -375,6 +380,9 @@ int main(int argc, char **argv, char **env) case 'C': dryrun = 1; break; + case 'u': + user_mode = 1; + break; case 'w': writeconfig = 1; break; @@ -425,11 +433,13 @@ int main(int argc, char **argv, char **env) vty_init_vtysh(); - /* Read vtysh configuration file before connecting to daemons. - * (file may not be readable to calling user in SUID mode) */ - suid_on(); - vtysh_read_config(vtysh_config); - suid_off(); + if (!user_mode) { + /* Read vtysh configuration file before connecting to daemons. + * (file may not be readable to calling user in SUID mode) */ + suid_on(); + vtysh_read_config(vtysh_config); + suid_off(); + } if (markfile) { if (!inputfile) { From 186f6af280a161eb75d1c6388c4dd94b421f892d Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Thu, 15 Mar 2018 18:11:06 -0400 Subject: [PATCH 2/3] vtysh: move user_mode to header file, keep checkpatch happy Signed-off-by: Lou Berger --- vtysh/vtysh.c | 1 - vtysh/vtysh.h | 2 ++ vtysh/vtysh_main.c | 7 +++++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index dca5dafa84..f8493ae89b 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -305,7 +305,6 @@ static int vtysh_execute_func(const char *line, int pager) int closepager = 0; int tried = 0; int saved_ret, saved_node; - extern int user_mode; /* Split readline string up into the vector. */ vline = cmd_make_strvec(line); diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 52a1a46105..9b21c3376a 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -100,4 +100,6 @@ extern int execute_flag; extern struct vty *vty; +extern int user_mode; + #endif /* VTYSH_H */ diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index b5cc1d21d1..4de671b7fa 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -61,7 +61,7 @@ static char history_file[MAXPATHLEN]; int execute_flag = 0; /* Flag to indicate if in user/unprivileged mode. */ -int user_mode = 0; +int user_mode; /* For sigsetjmp() & siglongjmp(). */ static sigjmp_buf jmpbuf; @@ -315,6 +315,8 @@ int main(int argc, char **argv, char **env) realgid = getgid(); suid_off(); + user_mode = 0; /* may be set in options processing */ + /* Preserve name of myself. */ progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]); @@ -323,7 +325,8 @@ int main(int argc, char **argv, char **env) /* Option handling. */ while (1) { - opt = getopt_long(argc, argv, "be:c:d:nf:mEhCwN:u", longopts, 0); + opt = getopt_long(argc, argv, "be:c:d:nf:mEhCwN:u", + longopts, 0); if (opt == EOF) break; From 5aa5df3995b7d206188fb0ed42e9a17bbcb73ed5 Mon Sep 17 00:00:00 2001 From: Lou Berger Date: Wed, 28 Mar 2018 10:56:06 -0400 Subject: [PATCH 3/3] manpages: vtysh.rst add description of -u/--user flags Signed-off-by: Lou Berger --- doc/manpages/vtysh.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/doc/manpages/vtysh.rst b/doc/manpages/vtysh.rst index 2db746020d..2efff37626 100644 --- a/doc/manpages/vtysh.rst +++ b/doc/manpages/vtysh.rst @@ -53,6 +53,10 @@ OPTIONS available for the vtysh command: When executing cli that does not invoke a vtysh shell, if an error ocurrs ignore it for purposes of return codes from vtysh. +.. option:: -u, --user + + Run as an unprivileged user. This limits access to non-privileged commands, i.e., the same commands when directly accessing a daemon before running the enable command. It also provides the same limited security as such direct access. + .. option:: -h, --help Display a usage message on standard output and exit.