diff options
author | Quentin Young <qlyoung@cumulusnetworks.com> | 2016-11-12 06:17:37 +0100 |
---|---|---|
committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2016-11-12 06:17:37 +0100 |
commit | 07321a065d1126c00766ca3d6698e57936699f82 (patch) | |
tree | a7dac2bb2248d87f40b1c3c2af7440d9bea35421 /vtysh | |
parent | lib, vtysh: Fix memory leaks, change cmd_element to const (diff) | |
parent | Merge remote-tracking branch 'opensourcerouting/cmaster-next-vty2' into cmast... (diff) | |
download | frr-07321a065d1126c00766ca3d6698e57936699f82.tar.xz frr-07321a065d1126c00766ca3d6698e57936699f82.zip |
Merge branch 'cmaster-next' into vtysh-grammar
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Conflicts:
lib/command.c
lib/vty.c
Diffstat (limited to 'vtysh')
-rw-r--r-- | vtysh/Makefile.am | 1 | ||||
-rw-r--r-- | vtysh/vtysh.c | 164 | ||||
-rw-r--r-- | vtysh/vtysh.h | 9 | ||||
-rw-r--r-- | vtysh/vtysh_config.c | 1 | ||||
-rw-r--r-- | vtysh/vtysh_main.c | 65 |
5 files changed, 134 insertions, 106 deletions
diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am index 58ffdfca2..0ff2d738f 100644 --- a/vtysh/Makefile.am +++ b/vtysh/Makefile.am @@ -86,6 +86,7 @@ vtysh_cmd_FILES = $(vtysh_scan) \ $(top_srcdir)/zebra/zebra_fpm.c \ $(top_srcdir)/zebra/zebra_ptm.c \ $(top_srcdir)/zebra/zebra_mpls_vty.c \ + $(top_srcdir)/watchquagga/watchquagga_vty.c \ $(BGP_VNC_RFAPI_SRC) $(BGP_VNC_RFP_SRC) vtysh_cmd.c: $(vtysh_cmd_FILES) extract.pl diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c index e8cf5aa23..85973bdb5 100644 --- a/vtysh/vtysh.c +++ b/vtysh/vtysh.c @@ -73,12 +73,11 @@ struct vtysh_client vtysh_client[] = { .fd = -1, .name = "bgpd", .flag = VTYSH_BGPD, .path = BGP_VTYSH_PATH, .next = NULL}, { .fd = -1, .name = "isisd", .flag = VTYSH_ISISD, .path = ISIS_VTYSH_PATH, .next = NULL}, { .fd = -1, .name = "pimd", .flag = VTYSH_PIMD, .path = PIM_VTYSH_PATH, .next = NULL}, + { .fd = -1, .name = "watchquagga", .flag = VTYSH_WATCHQUAGGA, .path = WATCHQUAGGA_VTYSH_PATH, .next = NULL}, }; enum vtysh_write_integrated vtysh_write_integrated = WRITE_INTEGRATED_UNSPECIFIED; -extern char config_default[]; - static void vclient_close (struct vtysh_client *vclient) { @@ -1068,7 +1067,7 @@ vtysh_end (void) return CMD_SUCCESS; } -DEFUNSH (VTYSH_ALL, +DEFUNSH (VTYSH_REALLYALL, vtysh_end_all, vtysh_end_all_cmd, "end", @@ -1410,8 +1409,8 @@ DEFUNSH (VTYSH_ALL, return CMD_SUCCESS; } -DEFUNSH (VTYSH_ALL, - vtysh_enable, +DEFUNSH (VTYSH_REALLYALL, + vtysh_enable, vtysh_enable_cmd, "enable", "Turn on privileged mode command\n") @@ -1420,8 +1419,8 @@ DEFUNSH (VTYSH_ALL, return CMD_SUCCESS; } -DEFUNSH (VTYSH_ALL, - vtysh_disable, +DEFUNSH (VTYSH_REALLYALL, + vtysh_disable, vtysh_disable_cmd, "disable", "Turn off privileged mode command\n") @@ -1431,7 +1430,7 @@ DEFUNSH (VTYSH_ALL, return CMD_SUCCESS; } -DEFUNSH (VTYSH_ALL, +DEFUNSH (VTYSH_REALLYALL, vtysh_config_terminal, vtysh_config_terminal_cmd, "configure terminal", @@ -1512,7 +1511,7 @@ vtysh_exit (struct vty *vty) return CMD_SUCCESS; } -DEFUNSH (VTYSH_ALL, +DEFUNSH (VTYSH_REALLYALL, vtysh_exit_all, vtysh_exit_all_cmd, "exit", @@ -2399,74 +2398,101 @@ backup_config_file (const char *fbackup) free (integrate_sav); } -static int -write_config_integrated(void) +int +vtysh_write_config_integrated(void) { u_int i; char line[] = "write terminal\n"; - FILE *fp, *fp1; + FILE *fp; + int fd; + struct passwd *pwentry; + struct group *grentry; + uid_t uid = -1; + gid_t gid = -1; + struct stat st; + int err = 0; fprintf (stdout,"Building Configuration...\n"); - backup_config_file(integrate_default); - backup_config_file(host.config); - - fp = fopen (integrate_default, "w"); + backup_config_file(quagga_config); + fp = fopen (quagga_config, "w"); if (fp == NULL) { - fprintf (stdout,"%% Can't open configuration file %s due to '%s'\n", - integrate_default, safe_strerror(errno)); - return CMD_SUCCESS; - } - - fp1 = fopen (host.config, "w"); - if (fp1 == NULL) - { - fprintf (stdout,"%% Can't open configuration file %s due to '%s'\n", - host.config, safe_strerror(errno)); - return CMD_SUCCESS; + fprintf (stdout,"%% Error: failed to open configuration file %s: %s\n", + quagga_config, safe_strerror(errno)); + return CMD_WARNING; } + fd = fileno (fp); - vtysh_config_write (); - vtysh_config_dump (fp1); - - fclose (fp1); for (i = 0; i < array_size(vtysh_client); i++) vtysh_client_config (&vtysh_client[i], line); vtysh_config_write (); vtysh_config_dump (fp); - fclose (fp); + if (fchmod (fd, CONFIGFILE_MASK) != 0) + { + printf ("%% Warning: can't chmod configuration file %s: %s\n", + quagga_config, safe_strerror(errno)); + err++; + } - if (chmod (integrate_default, CONFIGFILE_MASK) != 0) + pwentry = getpwnam (QUAGGA_USER); + if (pwentry) + uid = pwentry->pw_uid; + else { - fprintf (stdout,"%% Can't chmod configuration file %s: %s\n", - integrate_default, safe_strerror(errno)); - return CMD_WARNING; + printf ("%% Warning: could not look up user \"%s\"\n", QUAGGA_USER); + err++; } - if (chmod (host.config, CONFIGFILE_MASK) != 0) + grentry = getgrnam (QUAGGA_GROUP); + if (grentry) + gid = grentry->gr_gid; + else { - fprintf (stdout,"%% Can't chmod configuration file %s: %s (%d)\n", - integrate_default, safe_strerror(errno), errno); - return CMD_WARNING; + printf ("%% Warning: could not look up group \"%s\"\n", QUAGGA_GROUP); + err++; } - fprintf(stdout,"Integrated configuration saved to %s\n",integrate_default); - fprintf (stdout,"[OK]\n"); + if (!fstat (fd, &st)) + { + if (st.st_uid == uid) + uid = -1; + if (st.st_gid == gid) + gid = -1; + if ((uid != (uid_t)-1 || gid != (gid_t)-1) && fchown (fd, uid, gid)) + { + printf ("%% Warning: can't chown configuration file %s: %s\n", + quagga_config, safe_strerror(errno)); + err++; + } + } + else + { + printf ("%% Warning: stat() failed on %s: %s\n", + quagga_config, safe_strerror(errno)); + err++; + } + + fclose (fp); + printf ("Integrated configuration saved to %s\n", quagga_config); + if (err) + return CMD_WARNING; + + printf ("[OK]\n"); return CMD_SUCCESS; } -static bool vtysh_writeconfig_integrated(void) +static bool want_config_integrated(void) { struct stat s; switch (vtysh_write_integrated) { case WRITE_INTEGRATED_UNSPECIFIED: - if (stat(integrate_default, &s) && errno == ENOENT) + if (stat(quagga_config, &s) && errno == ENOENT) return false; return true; case WRITE_INTEGRATED_NO: @@ -2487,41 +2513,33 @@ DEFUN (vtysh_write_memory, int ret = CMD_SUCCESS; char line[] = "write memory\n"; u_int i; - FILE *fp; - - /* If integrated Quagga.conf explicitely set. */ - if (vtysh_writeconfig_integrated()) - return write_config_integrated(); - else - backup_config_file(integrate_default); - - fprintf (stdout,"Building Configuration...\n"); - - for (i = 0; i < array_size(vtysh_client); i++) - ret = vtysh_client_execute (&vtysh_client[i], line, stdout); + fprintf (stdout, "Note: this version of vtysh never writes vtysh.conf\n"); - fp = fopen(host.config, "w"); - if (fp == NULL) + /* If integrated Quagga.conf explicitely set. */ + if (want_config_integrated()) { - fprintf (stdout,"%% Can't open configuration file %s due to '%s'\n", - host.config, safe_strerror(errno)); - return CMD_SUCCESS; + ret = CMD_WARNING; + for (i = 0; i < array_size(vtysh_client); i++) + if (vtysh_client[i].flag == VTYSH_WATCHQUAGGA) + break; + if (i < array_size(vtysh_client) && vtysh_client[i].fd != -1) + ret = vtysh_client_execute (&vtysh_client[i], "write integrated", stdout); + + if (ret != CMD_SUCCESS) + { + printf("\nWarning: attempting direct configuration write without " + "watchquagga.\nFile permissions and ownership may be " + "incorrect, or write may fail.\n\n"); + ret = vtysh_write_config_integrated(); + } + return ret; } - vtysh_config_write (); - vtysh_config_dump (fp); - - fclose (fp); - - if (chmod (host.config, CONFIGFILE_MASK) != 0) - { - fprintf (stdout,"%% Can't chmod configuration file %s: %s\n", - integrate_default, safe_strerror(errno)); - return CMD_WARNING; - } + fprintf (stdout,"Building Configuration...\n"); - fprintf (stdout,"[OK]\n"); + for (i = 0; i < array_size(vtysh_client); i++) + ret = vtysh_client_execute (&vtysh_client[i], line, stdout); return ret; } diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h index 7241b4c12..dade049ad 100644 --- a/vtysh/vtysh.h +++ b/vtysh/vtysh.h @@ -34,7 +34,13 @@ DECLARE_MGROUP(MVTYSH) #define VTYSH_ISISD 0x40 #define VTYSH_PIMD 0x100 #define VTYSH_LDPD 0x200 +#define VTYSH_WATCHQUAGGA 0x400 +/* commands in REALLYALL are crucial to correct vtysh operation */ +#define VTYSH_REALLYALL ~0U +/* watchquagga is not in ALL since library CLI functions should not be + * run on it (logging & co. should stay in a fixed/frozen config, and + * things like prefix lists are not even initialised) */ #define VTYSH_ALL VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_BGPD|VTYSH_ISISD|VTYSH_PIMD #define VTYSH_RMAP VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_PIMD #define VTYSH_INTERFACE VTYSH_ZEBRA|VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_LDPD|VTYSH_ISISD|VTYSH_PIMD @@ -53,6 +59,8 @@ enum vtysh_write_integrated { extern enum vtysh_write_integrated vtysh_write_integrated; +extern char *quagga_config; + void vtysh_init_vty (void); void vtysh_init_cmd (void); extern int vtysh_connect_all (const char *optional_daemon_name); @@ -73,6 +81,7 @@ void config_add_line (struct list *, const char *); int vtysh_mark_file(const char *filename); int vtysh_read_config (const char *); +int vtysh_write_config_integrated (void); void vtysh_config_parse_line (const char *); diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 7ad457ee7..4ec0e0028 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -376,7 +376,6 @@ vtysh_read_config (const char *config_default_dir) FILE *confp = NULL; int ret; - host_config_set (config_default_dir); confp = fopen (config_default_dir, "r"); if (confp == NULL) { diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 751152e91..999d90ab2 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -35,7 +35,6 @@ #include "getopt.h" #include "command.h" #include "memory.h" -#include "privs.h" #include "linklist.h" #include "memory_vty.h" @@ -45,30 +44,10 @@ /* VTY shell program name. */ char *progname; -static zebra_capabilities_t _caps_p [] = -{ - ZCAP_BIND, - ZCAP_NET_RAW, - ZCAP_NET_ADMIN, -}; - -struct zebra_privs_t vtysh_privs = -{ -#if defined(QUAGGA_USER) && defined(QUAGGA_GROUP) - .user = QUAGGA_USER, - .group = QUAGGA_GROUP, -#endif -#ifdef VTY_GROUP - .vty_group = VTY_GROUP, -#endif - .caps_p = _caps_p, - .cap_num_p = array_size(_caps_p), - .cap_num_i = 0, -}; - /* Configuration file name and directory. */ -char config_default[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG; -char quagga_config_default[] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG; +static char vtysh_config_always[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG; +static char quagga_config_default[] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG; +char *quagga_config = quagga_config_default; char history_file[MAXPATHLEN]; /* Flag for indicate executing child command. */ @@ -166,6 +145,7 @@ usage (int status) "-E, --echo Echo prompt and command in -c mode\n" \ "-C, --dryrun Check configuration for validity and exit\n" \ "-m, --markfile Mark input file with context end\n" + "-w, --writeconfig Write integrated config (Quagga.conf) and exit\n" "-h, --help Display this help and exit\n\n" \ "Note that multiple commands may be executed from the command\n" \ "line by passing multiple -c args, or by embedding linefeed\n" \ @@ -189,6 +169,7 @@ struct option longopts[] = { "help", no_argument, NULL, 'h'}, { "noerror", no_argument, NULL, 'n'}, { "mark", no_argument, NULL, 'm'}, + { "writeconfig", no_argument, NULL, 'w'}, { 0 } }; @@ -289,6 +270,7 @@ main (int argc, char **argv, char **env) int echo_command = 0; int no_error = 0; int markfile = 0; + int writeconfig = 0; int ret = 0; char *homedir = NULL; @@ -302,7 +284,7 @@ main (int argc, char **argv, char **env) /* Option handling. */ while (1) { - opt = getopt_long (argc, argv, "be:c:d:nf:mEhC", longopts, 0); + opt = getopt_long (argc, argv, "be:c:d:nf:mEhCw", longopts, 0); if (opt == EOF) break; @@ -346,6 +328,9 @@ main (int argc, char **argv, char **env) case 'C': dryrun = 1; break; + case 'w': + writeconfig = 1; + break; case 'h': usage (0); break; @@ -355,12 +340,22 @@ main (int argc, char **argv, char **env) } } + if (markfile + writeconfig + dryrun + boot_flag > 1) + { + fprintf (stderr, "Invalid combination of arguments. Please specify at " + "most one of:\n\t-b, -C, -m, -w\n"); + return 1; + } + if (inputfile && (writeconfig || boot_flag)) + { + fprintf (stderr, "WARNING: Combinining the -f option with -b or -w is " + "NOT SUPPORTED since its\nresults are inconsistent!\n"); + } + /* Initialize user input buffer. */ line_read = NULL; setlinebuf(stdout); - zprivs_init (&vtysh_privs); - /* Signal and others. */ vtysh_signal_init (); @@ -373,7 +368,7 @@ main (int argc, char **argv, char **env) vty_init_vtysh (); /* Read vtysh configuration file before connecting to daemons. */ - vtysh_read_config(config_default); + vtysh_read_config(vtysh_config_always); if (markfile) { @@ -422,6 +417,12 @@ main (int argc, char **argv, char **env) exit(1); } + if (writeconfig) + { + vtysh_execute ("enable"); + return vtysh_write_config_integrated (); + } + if (inputfile) { vtysh_flock_config (inputfile); @@ -512,17 +513,17 @@ main (int argc, char **argv, char **env) history_truncate_file(history_file,1000); exit (0); } - + /* Boot startup configuration file. */ if (boot_flag) { - vtysh_flock_config (integrate_default); - int ret = vtysh_read_config (integrate_default); + vtysh_flock_config (quagga_config); + int ret = vtysh_read_config (quagga_config); vtysh_unflock_config (); if (ret) { fprintf (stderr, "Configuration file[%s] processing failure: %d\n", - integrate_default, ret); + quagga_config, ret); if (no_error) exit (0); else |