diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/command.c | 27 | ||||
| -rw-r--r-- | lib/command.h | 2 | ||||
| -rw-r--r-- | lib/log.c | 3 | ||||
| -rw-r--r-- | lib/log.h | 1 | ||||
| -rw-r--r-- | lib/network.c | 14 | ||||
| -rw-r--r-- | lib/network.h | 2 | ||||
| -rw-r--r-- | lib/pid_output.c | 3 | ||||
| -rw-r--r-- | lib/privs.c | 51 | ||||
| -rw-r--r-- | lib/vty.c | 17 |
9 files changed, 87 insertions, 33 deletions
diff --git a/lib/command.c b/lib/command.c index 593822a66e..bf7e269acc 100644 --- a/lib/command.c +++ b/lib/command.c @@ -1350,6 +1350,9 @@ DEFUN (config_write, return CMD_SUCCESS; } + if (host.noconfig) + return CMD_SUCCESS; + /* Check and see if we are operating under vtysh configuration */ if (host.config == NULL) { @@ -1478,6 +1481,11 @@ DEFUN (show_startup_config, char buf[BUFSIZ]; FILE *confp; + if (host.noconfig) + return CMD_SUCCESS; + if (host.config == NULL) + return CMD_WARNING; + confp = fopen (host.config, "r"); if (confp == NULL) { @@ -2281,7 +2289,11 @@ install_default (enum node_type node) install_element (node, &show_running_config_cmd); } -/* Initialize command interface. Install basic nodes and commands. */ +/* Initialize command interface. Install basic nodes and commands. + * + * terminal = 0 -- vtysh / no logging, no config control + * terminal = 1 -- normal daemon + * terminal = -1 -- watchquagga / no logging, but minimal config control */ void cmd_init (int terminal) { @@ -2296,6 +2308,7 @@ cmd_init (int terminal) host.enable = NULL; host.logfile = NULL; host.config = NULL; + host.noconfig = (terminal < 0); host.lines = -1; host.motd = default_motd; host.motdfile = NULL; @@ -2338,12 +2351,17 @@ cmd_init (int terminal) { install_element (ENABLE_NODE, &config_logmsg_cmd); install_default (CONFIG_NODE); + + install_element (VIEW_NODE, &show_thread_cpu_cmd); + install_element (ENABLE_NODE, &clear_thread_cpu_cmd); + + install_element (VIEW_NODE, &show_work_queues_cmd); } install_element (CONFIG_NODE, &hostname_cmd); install_element (CONFIG_NODE, &no_hostname_cmd); - if (terminal) + if (terminal > 0) { install_element (CONFIG_NODE, &password_cmd); install_element (CONFIG_NODE, &enable_password_cmd); @@ -2373,11 +2391,6 @@ cmd_init (int terminal) install_element (CONFIG_NODE, &service_terminal_length_cmd); install_element (CONFIG_NODE, &no_service_terminal_length_cmd); - install_element (VIEW_NODE, &show_thread_cpu_cmd); - - install_element (ENABLE_NODE, &clear_thread_cpu_cmd); - install_element (VIEW_NODE, &show_work_queues_cmd); - vrf_install_commands (); } srandom(time(NULL)); diff --git a/lib/command.h b/lib/command.h index 3bcd66468d..50323d3753 100644 --- a/lib/command.h +++ b/lib/command.h @@ -57,6 +57,7 @@ struct host /* config file name of this host */ char *config; + int noconfig; /* Flags for services */ int advanced; @@ -226,6 +227,7 @@ struct cmd_element #define CMD_COMPLETE_LIST_MATCH 9 #define CMD_SUCCESS_DAEMON 10 #define CMD_ERR_NO_FILE 11 +#define CMD_SUSPEND 12 /* Argc max counts. */ #define CMD_ARGC_MAX 25 @@ -58,7 +58,8 @@ const char *zlog_proto_names[] = "LDP", "ISIS", "PIM", - "RFP", + "RFP", + "WATCHQUAGGA", NULL, }; @@ -59,6 +59,7 @@ typedef enum ZLOG_ISIS, ZLOG_PIM, ZLOG_RFP, + ZLOG_WATCHQUAGGA, } zlog_proto_t; /* If maxlvl is set to ZLOG_DISABLED, then no messages will be sent diff --git a/lib/network.c b/lib/network.c index 5379ecb5a6..506e019136 100644 --- a/lib/network.c +++ b/lib/network.c @@ -94,6 +94,20 @@ set_nonblocking(int fd) return 0; } +int +set_cloexec(int fd) +{ + int flags; + flags = fcntl(fd, F_GETFD, 0); + if (flags == -1) + return -1; + + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) + return -1; + return 0; +} + float htonf (float host) { diff --git a/lib/network.h b/lib/network.h index 0fcb575d1c..a9126caf7f 100644 --- a/lib/network.h +++ b/lib/network.h @@ -33,6 +33,8 @@ extern int writen (int, const u_char *, int); -1 on error. */ extern int set_nonblocking(int fd); +extern int set_cloexec(int fd); + /* Does the I/O error indicate that the operation should be retried later? */ #define ERRNO_IO_RETRY(EN) \ (((EN) == EAGAIN) || ((EN) == EWOULDBLOCK) || ((EN) == EINTR)) diff --git a/lib/pid_output.c b/lib/pid_output.c index 5261babc6d..de4c2fba99 100644 --- a/lib/pid_output.c +++ b/lib/pid_output.c @@ -24,6 +24,7 @@ #include <fcntl.h> #include <log.h> #include "version.h" +#include "network.h" #define PIDFILE_MASK 0644 #ifndef HAVE_FCNTL @@ -84,6 +85,8 @@ pid_output (const char *path) umask(oldumask); memset (&lock, 0, sizeof(lock)); + set_cloexec(fd); + lock.l_type = F_WRLCK; lock.l_whence = SEEK_SET; diff --git a/lib/privs.c b/lib/privs.c index 6cf87c18d4..ac2a8454c5 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -679,6 +679,15 @@ zprivs_init(struct zebra_privs_t *zprivs) exit (1); } + if (zprivs->vty_group) + { + /* in a "NULL" setup, this is allowed to fail too, but still try. */ + if ((grentry = getgrnam (zprivs->vty_group))) + zprivs_state.vtygrp = grentry->gr_gid; + else + zprivs_state.vtygrp = (gid_t)-1; + } + /* NULL privs */ if (! (zprivs->user || zprivs->group || zprivs->cap_num_p || zprivs->cap_num_i) ) @@ -731,34 +740,30 @@ zprivs_init(struct zebra_privs_t *zprivs) if (zprivs->vty_group) /* Add the vty_group to the supplementary groups so it can be chowned to */ { - if ( (grentry = getgrnam (zprivs->vty_group)) ) - { - zprivs_state.vtygrp = grentry->gr_gid; - - for ( i = 0; i < ngroups; i++ ) - if ( groups[i] == zprivs_state.vtygrp ) - { - found++; - break; - } - - if (!found) - { - fprintf (stderr, "privs_init: user(%s) is not part of vty group specified(%s)\n", - zprivs->user, zprivs->vty_group); - exit (1); - } - if ( i >= ngroups && ngroups < (int) ZEBRA_NUM_OF(groups) ) - { - groups[i] = zprivs_state.vtygrp; - } - } - else + if (zprivs_state.vtygrp == (gid_t)-1) { fprintf (stderr, "privs_init: could not lookup vty group %s\n", zprivs->vty_group); exit (1); } + + for ( i = 0; i < ngroups; i++ ) + if ( groups[i] == zprivs_state.vtygrp ) + { + found++; + break; + } + + if (!found) + { + fprintf (stderr, "privs_init: user(%s) is not part of vty group specified(%s)\n", + zprivs->user, zprivs->vty_group); + exit (1); + } + if ( i >= ngroups && ngroups < (int) ZEBRA_NUM_OF(groups) ) + { + groups[i] = zprivs_state.vtygrp; + } } if (ngroups) @@ -1839,6 +1839,7 @@ vty_accept (struct thread *thread) return -1; } set_nonblocking(vty_sock); + set_cloexec(vty_sock); sockunion2hostprefix (&su, &p); @@ -1937,6 +1938,7 @@ vty_serv_sock_addrinfo (const char *hostname, unsigned short port) sockopt_v6only (ainfo->ai_family, sock); sockopt_reuseaddr (sock); sockopt_reuseport (sock); + set_cloexec (sock); ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen); if (ret < 0) @@ -2004,6 +2006,7 @@ vty_serv_sock_family (const char* addr, unsigned short port, int family) /* This is server, so reuse address. */ sockopt_reuseaddr (accept_sock); sockopt_reuseport (accept_sock); + set_cloexec (accept_sock); /* Bind socket to universal address and given port. */ ret = sockunion_bind (accept_sock, &su, port, naddr); @@ -2066,6 +2069,8 @@ vty_serv_un (const char *path) len = sizeof (serv.sun_family) + strlen (serv.sun_path); #endif /* HAVE_STRUCT_SOCKADDR_UN_SUN_LEN */ + set_cloexec (sock); + ret = bind (sock, (struct sockaddr *) &serv, len); if (ret < 0) { @@ -2133,6 +2138,7 @@ vtysh_accept (struct thread *thread) close (sock); return -1; } + set_cloexec(sock); #ifdef VTYSH_DEBUG printf ("VTY shell accept\n"); @@ -2227,8 +2233,15 @@ vtysh_read (struct thread *thread) printf ("vtysh node: %d\n", vty->node); #endif /* VTYSH_DEBUG */ - header[3] = ret; - buffer_put(vty->obuf, header, 4); + /* hack for asynchronous "write integrated" + * - other commands in "buf" will be ditched + * - input during pending config-write is "unsupported" */ + if (ret == CMD_SUSPEND) + break; + + /* warning: watchquagga hardcodes this result write */ + header[3] = ret; + buffer_put(vty->obuf, header, 4); if (!vty->t_write && (vtysh_flush(vty) < 0)) /* Try to flush results; exit if a write error occurs. */ |
