Merge pull request #1894 from LabNConsulting/working/master/vtysh-not-enabled

vtysh: add -u/--user flag to run commands without enable
This commit is contained in:
Quentin Young 2018-04-03 11:50:35 -04:00 committed by GitHub
commit 2d75202acc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 35 additions and 9 deletions

View File

@ -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. 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 .. option:: -h, --help
Display a usage message on standard output and exit. Display a usage message on standard output and exit.

View File

@ -312,6 +312,13 @@ static int vtysh_execute_func(const char *line, int pager)
if (vline == NULL) if (vline == NULL)
return CMD_SUCCESS; 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_ret = ret = cmd_execute_command(vline, vty, &cmd, 1);
saved_node = vty->node; saved_node = vty->node;
@ -387,13 +394,13 @@ static int vtysh_execute_func(const char *line, int pager)
fprintf(stdout, "Warning...\n"); fprintf(stdout, "Warning...\n");
break; break;
case CMD_ERR_AMBIGUOUS: case CMD_ERR_AMBIGUOUS:
fprintf(stdout, "%% Ambiguous command.\n"); fprintf(stdout, "%% Ambiguous command: %s\n", line);
break; break;
case CMD_ERR_NO_MATCH: case CMD_ERR_NO_MATCH:
fprintf(stdout, "%% Unknown command.\n"); fprintf(stdout, "%% Unknown command: %s\n", line);
break; break;
case CMD_ERR_INCOMPLETE: case CMD_ERR_INCOMPLETE:
fprintf(stdout, "%% Command incomplete.\n"); fprintf(stdout, "%% Command incomplete: %s\n", line);
break; break;
case CMD_SUCCESS_DAEMON: { case CMD_SUCCESS_DAEMON: {
/* /*

View File

@ -100,4 +100,6 @@ extern int execute_flag;
extern struct vty *vty; extern struct vty *vty;
extern int user_mode;
#endif /* VTYSH_H */ #endif /* VTYSH_H */

View File

@ -60,6 +60,9 @@ static char history_file[MAXPATHLEN];
/* Flag for indicate executing child command. */ /* Flag for indicate executing child command. */
int execute_flag = 0; int execute_flag = 0;
/* Flag to indicate if in user/unprivileged mode. */
int user_mode;
/* For sigsetjmp() & siglongjmp(). */ /* For sigsetjmp() & siglongjmp(). */
static sigjmp_buf jmpbuf; static sigjmp_buf jmpbuf;
@ -150,6 +153,7 @@ static void usage(int status)
" --vty_socket Override vty socket path\n" " --vty_socket Override vty socket path\n"
" --config_dir Override config directory path\n" " --config_dir Override config directory path\n"
"-N --pathspace Insert prefix into config & socket paths\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" "-w, --writeconfig Write integrated config (frr.conf) and exit\n"
"-h, --help Display this help and exit\n\n" "-h, --help Display this help and exit\n\n"
"Note that multiple commands may be executed from the command\n" "Note that multiple commands may be executed from the command\n"
@ -180,6 +184,7 @@ struct option longopts[] = {
{"mark", no_argument, NULL, 'm'}, {"mark", no_argument, NULL, 'm'},
{"writeconfig", no_argument, NULL, 'w'}, {"writeconfig", no_argument, NULL, 'w'},
{"pathspace", required_argument, NULL, 'N'}, {"pathspace", required_argument, NULL, 'N'},
{"user", no_argument, NULL, 'u'},
{0}}; {0}};
/* Read a string, and return a pointer to it. Returns NULL on EOF. */ /* Read a string, and return a pointer to it. Returns NULL on EOF. */
@ -310,6 +315,8 @@ int main(int argc, char **argv, char **env)
realgid = getgid(); realgid = getgid();
suid_off(); suid_off();
user_mode = 0; /* may be set in options processing */
/* Preserve name of myself. */ /* Preserve name of myself. */
progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]); progname = ((p = strrchr(argv[0], '/')) ? ++p : argv[0]);
@ -318,7 +325,8 @@ int main(int argc, char **argv, char **env)
/* Option handling. */ /* Option handling. */
while (1) { 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) if (opt == EOF)
break; break;
@ -375,6 +383,9 @@ int main(int argc, char **argv, char **env)
case 'C': case 'C':
dryrun = 1; dryrun = 1;
break; break;
case 'u':
user_mode = 1;
break;
case 'w': case 'w':
writeconfig = 1; writeconfig = 1;
break; break;
@ -425,11 +436,13 @@ int main(int argc, char **argv, char **env)
vty_init_vtysh(); vty_init_vtysh();
/* Read vtysh configuration file before connecting to daemons. if (!user_mode) {
* (file may not be readable to calling user in SUID mode) */ /* Read vtysh configuration file before connecting to daemons.
suid_on(); * (file may not be readable to calling user in SUID mode) */
vtysh_read_config(vtysh_config); suid_on();
suid_off(); vtysh_read_config(vtysh_config);
suid_off();
}
if (markfile) { if (markfile) {
if (!inputfile) { if (!inputfile) {