]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #120 from opensourcerouting/snapcraft-base-v3
authorRuss White <russ@riw.us>
Wed, 25 Jan 2017 20:04:49 +0000 (15:04 -0500)
committerGitHub <noreply@github.com>
Wed, 25 Jan 2017 20:04:49 +0000 (15:04 -0500)
Snapcraft base changes

22 files changed:
bgpd/bgp_main.c
isisd/isis_main.c
ldpd/control.c
ldpd/ldp_vty_exec.c
ldpd/ldpd.c
ldpd/ldpd.h
ldpd/ldpe.c
ldpd/ldpe.h
lib/privs.c
lib/sockopt.c
lib/sockopt.h
lib/vty.c
ospf6d/ospf6_main.c
ospfd/ospf_main.c
pimd/pim_main.c
ripd/rip_main.c
ripngd/ripng_main.c
vtysh/vtysh.c
vtysh/vtysh.h
vtysh/vtysh_main.c
vtysh/vtysh_user.c
zebra/main.c

index 33191f0a982bbcde6c66e92df28c782189ca1f89..e6f5cdcb67d6bddcf4cf2ec14c524c453aa36495 100644 (file)
@@ -59,6 +59,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #endif
 
 /* bgpd options, we use GNU getopt library. */
+#define OPTION_VTYSOCK 1000
 static const struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
@@ -69,6 +70,7 @@ static const struct option longopts[] =
   { "listenon",    required_argument, NULL, 'l'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "vty_socket",  required_argument, NULL, OPTION_VTYSOCK },
   { "retain",      no_argument,       NULL, 'r'},
   { "no_kernel",   no_argument,       NULL, 'n'},
   { "user",        required_argument, NULL, 'u'},
@@ -111,6 +113,9 @@ static struct quagga_signal_t bgp_signals[] =
 /* Configuration file and directory. */
 char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = BGP_VTYSH_PATH;
+
 /* Route retain mode flag. */
 static int retain_mode = 0;
 
@@ -123,6 +128,7 @@ static const char *pid_file = PATH_BGPD_PID;
 /* VTY port number and address.  */
 int vty_port = BGP_VTY_PORT;
 char *vty_addr = NULL;
+char *vty_sock_name;
 
 /* privileges */
 static zebra_capabilities_t _caps_p [] =  
@@ -165,6 +171,7 @@ redistribution between different routing protocols.\n\n\
 -l, --listenon     Listen on specified address (implies -n)\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
 -r, --retain       When program terminates, retain added route by bgpd.\n\
 -n, --no_kernel    Do not install route to kernel.\n\
 -u, --user         User to run as\n\
@@ -195,7 +202,7 @@ sighup (void)
   vty_read_config (config_file, config_default);
 
   /* Create VTY's socket */
-  vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Try to return to normal operation. */
 }
@@ -469,6 +476,9 @@ main (int argc, char **argv)
          if (vty_port <= 0 || vty_port > 0xffff)
            vty_port = BGP_VTY_PORT;
          break;
+       case OPTION_VTYSOCK:
+         set_socket_path(vty_sock_path, BGP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+         break;
        case 'r':
          retain_mode = 1;
          break;
@@ -544,7 +554,7 @@ main (int argc, char **argv)
   pid_output (pid_file);
 
   /* Make bgp vty socket. */
-  vty_serv_sock (vty_addr, vty_port, BGP_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Print banner. */
   zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", FRR_COPYRIGHT,
index f34be99eca791f495e6be416400bbf7dee917a16..865f5c5f9455cf50b313befc5c5946df2d5d007d 100644 (file)
@@ -81,6 +81,7 @@ struct zebra_privs_t isisd_privs = {
 };
 
 /* isisd options */
+#define OPTION_VTYSOCK 1000
 struct option longopts[] = {
   {"daemon",      no_argument,       NULL, 'd'},
   {"config_file", required_argument, NULL, 'f'},
@@ -88,6 +89,7 @@ struct option longopts[] = {
   {"socket",      required_argument, NULL, 'z'},
   {"vty_addr",    required_argument, NULL, 'A'},
   {"vty_port",    required_argument, NULL, 'P'},
+  {"vty_socket",  required_argument, NULL, OPTION_VTYSOCK},
   {"user",        required_argument, NULL, 'u'},
   {"group",       required_argument, NULL, 'g'},
   {"version",     no_argument,       NULL, 'v'},
@@ -103,6 +105,9 @@ char *config_file = NULL;
 /* isisd program name. */
 char *progname;
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = ISIS_VTYSH_PATH;
+
 int daemon_mode = 0;
 
 /* Master of threads. */
@@ -144,6 +149,7 @@ Daemon which manages IS-IS routing\n\n\
 -z, --socket       Set path of zebra socket\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
 -u, --user         User to run as\n\
 -g, --group        Group to run as\n\
 -v, --version      Print program version\n\
@@ -240,6 +246,7 @@ main (int argc, char **argv, char **envp)
   struct thread thread;
   char *config_file = NULL;
   char *vty_addr = NULL;
+  char *vty_sock_name;
   int dryrun = 0;
 
   /* Get the programname without the preceding path. */
@@ -305,6 +312,9 @@ main (int argc, char **argv, char **envp)
          vty_port = atoi (optarg);
          vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
          break;
+       case OPTION_VTYSOCK:
+         set_socket_path(vty_sock_path, ISIS_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+         break;
        case 'u':
          isisd_privs.user = optarg;
          break;
@@ -379,7 +389,7 @@ main (int argc, char **argv, char **envp)
     pid_output (pid_file);
 
   /* Make isis vty socket. */
-  vty_serv_sock (vty_addr, vty_port, ISIS_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Print banner. */
   zlog_notice ("Quagga-ISISd %s starting: vty@%d", FRR_VERSION, vty_port);
index ba303cc12cdf62694b4f555589f27e1b1e8eea3e..8a2280be07bf54ae36e0d1bb91655a635415bb53 100644 (file)
@@ -51,28 +51,28 @@ control_init(void)
 
        memset(&s_un, 0, sizeof(s_un));
        s_un.sun_family = AF_UNIX;
-       strlcpy(s_un.sun_path, LDPD_SOCKET, sizeof(s_un.sun_path));
+       strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
 
-       if (unlink(LDPD_SOCKET) == -1)
+       if (unlink(ctl_sock_path) == -1)
                if (errno != ENOENT) {
-                       log_warn("%s: unlink %s", __func__, LDPD_SOCKET);
+                       log_warn("%s: unlink %s", __func__, ctl_sock_path);
                        close(fd);
                        return (-1);
                }
 
        old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
        if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
-               log_warn("%s: bind: %s", __func__, LDPD_SOCKET);
+               log_warn("%s: bind: %s", __func__, ctl_sock_path);
                close(fd);
                umask(old_umask);
                return (-1);
        }
        umask(old_umask);
 
-       if (chmod(LDPD_SOCKET, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
+       if (chmod(ctl_sock_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
                log_warn("%s: chmod", __func__);
                close(fd);
-               (void)unlink(LDPD_SOCKET);
+               (void)unlink(ctl_sock_path);
                return (-1);
        }
 
@@ -97,7 +97,7 @@ control_cleanup(void)
 {
        accept_del(control_fd);
        close(control_fd);
-       unlink(LDPD_SOCKET);
+       unlink(ctl_sock_path);
 }
 
 /* ARGSUSED */
index a57cf3c3f6b7bf6ff16d539d274431160de17d06..a9138be2f2491035d66bfbc2884829e0dd81485e 100644 (file)
@@ -405,9 +405,9 @@ ldp_vty_connect(struct imsgbuf *ibuf)
 
        memset(&s_un, 0, sizeof(s_un));
        s_un.sun_family = AF_UNIX;
-       strlcpy(s_un.sun_path, LDPD_SOCKET, sizeof(s_un.sun_path));
+       strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
        if (connect(ctl_sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
-               log_warn("%s: connect: %s", __func__, LDPD_SOCKET);
+               log_warn("%s: connect: %s", __func__, ctl_sock_path);
                close(ctl_sock);
                return (-1);
        }
index 8a9847bdfd26a059cfdb99be1efb72ab2d8b7995..40726ba0bb8fb84d0a572e2cc429880f58bfb1d5 100644 (file)
@@ -43,7 +43,7 @@
 
 static void             ldpd_shutdown(void);
 static pid_t            start_child(enum ldpd_process, char *, int,
-                           const char *, const char *);
+                           const char *, const char *, const char *);
 static int              main_dispatch_ldpe(struct thread *);
 static int              main_dispatch_lde(struct thread *);
 static int              main_imsg_send_ipc_sockets(struct imsgbuf *,
@@ -115,7 +115,15 @@ struct zebra_privs_t ldpd_privs =
        .cap_num_i = 0
 };
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = LDP_VTYSH_PATH;
+
+/* CTL Socket path */
+char ctl_sock_path[MAXPATHLEN] = LDPD_SOCKET;
+
 /* LDPd options. */
+#define OPTION_VTYSOCK 1000
+#define OPTION_CTLSOCK 1001
 static struct option longopts[] =
 {
        { "daemon",      no_argument,       NULL, 'd'},
@@ -126,6 +134,8 @@ static struct option longopts[] =
        { "help",        no_argument,       NULL, 'h'},
        { "vty_addr",    required_argument, NULL, 'A'},
        { "vty_port",    required_argument, NULL, 'P'},
+       { "vty_socket",  required_argument, NULL, OPTION_VTYSOCK},
+       { "ctl_socket",  required_argument, NULL, OPTION_CTLSOCK},
        { "user",        required_argument, NULL, 'u'},
        { "group",       required_argument, NULL, 'g'},
        { "version",     no_argument,       NULL, 'v'},
@@ -148,6 +158,8 @@ Daemon which manages LDP.\n\n\
 -z, --socket       Set path of zebra socket\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
+    --ctl_socket   Override ctl socket path\n\
 -u, --user         User to run as\n\
 -g, --group        Group to run as\n\
 -v, --version      Print program version\n\
@@ -212,6 +224,9 @@ main(int argc, char *argv[])
        char                    *p;
        char                    *vty_addr = NULL;
        int                      vty_port = LDP_VTY_PORT;
+       char                    *vty_sock_name;
+       char                    *ctl_sock_custom_path = NULL;
+       char                    *ctl_sock_name;
        int                      daemon_mode = 0;
        const char              *user = NULL;
        const char              *group = NULL;
@@ -272,6 +287,28 @@ main(int argc, char *argv[])
                        if (vty_port <= 0 || vty_port > 0xffff)
                                vty_port = LDP_VTY_PORT;
                        break;
+               case OPTION_VTYSOCK:
+                       set_socket_path(vty_sock_path, LDP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+                       break;
+               case OPTION_CTLSOCK:
+                       ctl_sock_name = strrchr(LDPD_SOCKET, '/');
+                       if (ctl_sock_name)
+                               /* skip '/' */
+                               ctl_sock_name++;
+                       else
+                               /*
+                                * LDPD_SOCKET configured as relative path
+                                * during config? Should really never happen for
+                                * sensible config
+                                */
+                               ctl_sock_name = (char *)LDPD_SOCKET;
+                       ctl_sock_custom_path = optarg;
+                       strlcpy(ctl_sock_path, ctl_sock_custom_path,
+                           sizeof(ctl_sock_path));
+                       strlcat(ctl_sock_path, "/", sizeof(ctl_sock_path));
+                       strlcat(ctl_sock_path, ctl_sock_name,
+                           sizeof(ctl_sock_path));
+                       break;
                case 'u':
                        user = optarg;
                        break;
@@ -318,7 +355,7 @@ main(int argc, char *argv[])
        if (lflag)
                lde(user, group);
        else if (eflag)
-               ldpe(user, group);
+               ldpe(user, group, ctl_sock_path);
 
        master = thread_master_create();
 
@@ -360,9 +397,9 @@ main(int argc, char *argv[])
 
        /* start children */
        lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
-           pipe_parent2lde[1], user, group);
+           pipe_parent2lde[1], user, group, ctl_sock_custom_path);
        ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
-           pipe_parent2ldpe[1], user, group);
+           pipe_parent2ldpe[1], user, group, ctl_sock_custom_path);
 
        /* drop privileges */
        if (user)
@@ -410,7 +447,7 @@ main(int argc, char *argv[])
        pid_output(pid_file);
 
        /* Create VTY socket */
-       vty_serv_sock(vty_addr, vty_port, LDP_VTYSH_PATH);
+       vty_serv_sock(vty_addr, vty_port, vty_sock_path);
 
        /* Print banner. */
        log_notice("LDPd %s starting: vty@%d", FRR_VERSION, vty_port);
@@ -458,9 +495,9 @@ ldpd_shutdown(void)
 
 static pid_t
 start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
-    const char *group)
+    const char *group, const char *ctl_sock_custom_path)
 {
-       char    *argv[7];
+       char    *argv[9];
        int      argc = 0;
        pid_t    pid;
 
@@ -496,6 +533,10 @@ start_child(enum ldpd_process p, char *argv0, int fd, const char *user,
                argv[argc++] = (char *)"-g";
                argv[argc++] = (char *)group;
        }
+       if (ctl_sock_custom_path) {
+               argv[argc++] = (char *)"--ctl_socket";
+               argv[argc++] = (char *)ctl_sock_custom_path;
+       }
        argv[argc++] = NULL;
 
        execvp(argv0, argv);
index 630b192489d2625d9a758fb8fbfc6c9cfb316459..e58d8e4852c5706336e97562e9b0ced2c48cc99d 100644 (file)
@@ -672,6 +672,7 @@ int          sock_set_ipv6_mcast_loop(int);
 
 /* quagga */
 extern struct thread_master    *master;
+extern char                     ctl_sock_path[MAXPATHLEN];
 
 /* ldp_zebra.c */
 void           ldp_zebra_init(struct thread_master *);
index 37a3d79a289a47328d03b1e87404e78840f70a62..0d0fe5c9e92ab271fc78339f03c9738d83ccce3f 100644 (file)
@@ -99,7 +99,7 @@ static struct quagga_signal_t ldpe_signals[] =
 
 /* label distribution protocol engine */
 void
-ldpe(const char *user, const char *group)
+ldpe(const char *user, const char *group, const char *ctl_path)
 {
        struct thread            thread;
 
@@ -128,6 +128,7 @@ ldpe(const char *user, const char *group)
                ldpe_privs.group = group;
        zprivs_init(&ldpe_privs);
 
+       strlcpy(ctl_sock_path, ctl_path, sizeof(ctl_sock_path));
        if (control_init() == -1)
                fatalx("control socket setup failed");
 
index aab1a7fd9b918cebf6f4f90fb7ee79ff675776b2..da90c7cad777593480c5429da5704d199c1f7efe 100644 (file)
@@ -183,7 +183,7 @@ int  tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
            uint16_t, struct map *);
 
 /* ldpe.c */
-void            ldpe(const char *, const char *);
+void            ldpe(const char *, const char *, const char *);
 int             ldpe_imsg_compose_parent(int, pid_t, void *,
                    uint16_t);
 int             ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,
index ac2a8454c5f56b175d28aca425ef091b9ac0778f..376d6f3365bb8c22f50397420acabbb554492493 100644 (file)
@@ -251,7 +251,8 @@ zprivs_caps_init (struct zebra_privs_t *zprivs)
     }
 
   /* we have caps, we have no need to ever change back the original user */
-  if (zprivs_state.zuid)
+    /* only change uid if we don't have the correct one */
+    if ((zprivs_state.zuid) && (zprivs_state.zsuid != zprivs_state.zuid))
     {
       if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
         {
@@ -531,7 +532,8 @@ zprivs_caps_init (struct zebra_privs_t *zprivs)
   /* we have caps, we have no need to ever change back the original user
    * change real, effective and saved to the specified user.
    */
-  if (zprivs_state.zuid)
+   /* only change uid if we don't have the correct one */
+   if ((zprivs_state.zuid) && (zprivs_state.zsuid != zprivs_state.zuid))
     {
       if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
         {
@@ -602,7 +604,8 @@ zprivs_caps_terminate (void)
 int
 zprivs_change_uid (zebra_privs_ops_t op)
 {
-
+  if (zprivs_state.zsuid == zprivs_state.zuid)
+    return 0;
   if (op == ZPRIVS_RAISE)
     return seteuid (zprivs_state.zsuid);
   else if (op == ZPRIVS_LOWER)
@@ -766,7 +769,8 @@ zprivs_init(struct zebra_privs_t *zprivs)
         }
     }
 
-  if (ngroups)
+  /* add groups only if we changed uid - otherwise skip */
+  if ((ngroups) && (zprivs_state.zsuid != zprivs_state.zuid))
     {
       if ( setgroups (ngroups, groups) )
         {
@@ -776,7 +780,8 @@ zprivs_init(struct zebra_privs_t *zprivs)
         }
     }
 
-  if (zprivs_state.zgid)
+  /* change gid only if we changed uid - otherwise skip */
+  if ((zprivs_state.zgid) && (zprivs_state.zsuid != zprivs_state.zuid))
     {
       /* change group now, forever. uid we do later */
       if ( setregid (zprivs_state.zgid, zprivs_state.zgid) )
@@ -797,7 +802,8 @@ zprivs_init(struct zebra_privs_t *zprivs)
    * This is not worth that much security wise, but all we can do.
    */
   zprivs_state.zsuid = geteuid();  
-  if ( zprivs_state.zuid )
+  /* only change uid if we don't have the correct one */
+  if (( zprivs_state.zuid ) && (zprivs_state.zsuid != zprivs_state.zuid))
     {
       if ( setreuid (-1, zprivs_state.zuid) )
         {
@@ -824,7 +830,8 @@ zprivs_terminate (struct zebra_privs_t *zprivs)
 #ifdef HAVE_CAPABILITIES
   zprivs_caps_terminate();
 #else /* !HAVE_CAPABILITIES */
-  if (zprivs_state.zuid)
+  /* only change uid if we don't have the correct one */
+  if ((zprivs_state.zuid) && (zprivs_state.zsuid != zprivs_state.zuid))
     {
       if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
         {
index 461e1f7f5469d8dfc2c1390ec9eccfff0aced3d5..570b575a7ae8ec3fe4e34d756fac78e32af0c30a 100644 (file)
 #include "sockopt.h"
 #include "sockunion.h"
 
+/* Replace the path of given defaultpath with newpath, but keep filename */
+void
+set_socket_path (char *path, char *defaultpath, char *newpath, int maxsize)
+{
+  char *sock_name;
+
+  sock_name = strrchr(defaultpath, '/');
+  if (sock_name)
+    /* skip '/' */
+    sock_name++;
+  else
+    /*
+     * VTYSH_PATH configured as relative path
+     * during config? Should really never happen for
+     * sensible config
+     */
+    sock_name = defaultpath;
+
+  strlcpy (path, newpath, maxsize);
+  strlcat (path, "/", maxsize);
+  strlcat (path, sock_name, maxsize);
+}
+
 void
 setsockopt_so_recvbuf (int sock, int size)
 {
index b3ab57ab716c7ad8499b0ec213845efcff5c76eb..8e7895dd6f8c909520481f0d5c6558bf4e4907d3 100644 (file)
@@ -24,6 +24,9 @@
 
 #include "sockunion.h"
 
+/* Override (vty) socket paths, but keep the filename */
+extern void set_socket_path (char *path, char *defaultpath, char *newpath, int maxsize);
+
 extern void setsockopt_so_recvbuf (int sock, int size);
 extern void setsockopt_so_sendbuf (const int sock, int size);
 extern int getsockopt_so_sendbuf (const int sock);
index adcfaca4f3d4f4b8faeb0816d65009a033d0eaae..9594d68ebdf0c5e350ce9302a5bcfa9651959e34 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -2091,8 +2091,11 @@ vty_serv_un (const char *path)
   umask (old_mask);
 
   zprivs_get_ids(&ids);
-  
-  if (ids.gid_vty > 0)
+
+  /* Hack: ids.gid_vty is actually a uint, but we stored -1 in it
+     earlier for the case when we don't need to chown the file
+     type casting it here to make a compare */
+  if ((int)ids.gid_vty > 0)
     {
       /* set group of socket */
       if ( chown (path, -1, ids.gid_vty) )
index bd3a2faa5dcceed4cfbd6d96a9f25f8d0c7ee21b..68d2b6894d6b8f6defba97a354f60a242c62df0c 100644 (file)
@@ -51,6 +51,9 @@
 /* Default configuration file name for ospf6d. */
 #define OSPF6_DEFAULT_CONFIG       "ospf6d.conf"
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = OSPF6_VTYSH_PATH;
+
 /* Default port values. */
 #define OSPF6_VTY_PORT             2606
 
@@ -78,6 +81,7 @@ struct zebra_privs_t ospf6d_privs =
 };
 
 /* ospf6d options, we use GNU getopt library. */
+#define OPTION_VTYSOCK 1000
 struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
@@ -86,6 +90,7 @@ struct option longopts[] =
   { "socket",      required_argument, NULL, 'z'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "vty_socket",  required_argument, NULL, OPTION_VTYSOCK},
   { "user",        required_argument, NULL, 'u'},
   { "group",       required_argument, NULL, 'g'},
   { "version",     no_argument,       NULL, 'v'},
@@ -125,6 +130,7 @@ Daemon which manages OSPF version 3.\n\n\
 -z, --socket       Set path of zebra socket\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
 -u, --user         User to run as\n\
 -g, --group        Group to run as\n\
 -v, --version      Print program version\n\
@@ -233,6 +239,7 @@ main (int argc, char *argv[], char *envp[])
   int opt;
   char *vty_addr = NULL;
   int vty_port = 0;
+  char *vty_sock_name;
   char *config_file = NULL;
   struct thread thread;
   int dryrun = 0;
@@ -285,6 +292,9 @@ main (int argc, char *argv[], char *envp[])
           if (vty_port <= 0 || vty_port > 0xffff)
             vty_port = OSPF6_VTY_PORT;
           break;
+        case OPTION_VTYSOCK:
+          set_socket_path(vty_sock_path, OSPF6_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+          break;
         case 'u':
           ospf6d_privs.user = optarg;
           break;
@@ -357,7 +367,7 @@ main (int argc, char *argv[], char *envp[])
   /* Make ospf6 vty socket. */
   if (!vty_port)
     vty_port = OSPF6_VTY_PORT;
-  vty_serv_sock (vty_addr, vty_port, OSPF6_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Print start message */
   zlog_notice ("OSPF6d (Quagga-%s ospf6d-%s) starts: vty@%d",
index e0719b397a67fde77a11f80910171256b8428f2f..6719eb24970b8d244a3caf99a81ea96726b82dd3 100644 (file)
@@ -79,6 +79,7 @@ struct zebra_privs_t ospfd_privs =
 char config_default[100];
 
 /* OSPFd options. */
+#define OPTION_VTYSOCK 1000
 struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
@@ -90,6 +91,7 @@ struct option longopts[] =
   { "help",        no_argument,       NULL, 'h'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "vty_socket",  required_argument, NULL, OPTION_VTYSOCK},
   { "user",        required_argument, NULL, 'u'},
   { "group",       required_argument, NULL, 'g'},
   { "apiserver",   no_argument,       NULL, 'a'},
@@ -99,6 +101,9 @@ struct option longopts[] =
 
 /* OSPFd program name */
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = OSPF_VTYSH_PATH;
+
 /* Master of threads. */
 struct thread_master *master;
 
@@ -126,6 +131,7 @@ Daemon which manages OSPF.\n\n\
 -z, --socket       Set path of zebra socket\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
 -u, --user         User to run as\n\
 -g, --group        Group to run as\n\
 -a. --apiserver    Enable OSPF apiserver\n\
@@ -188,6 +194,7 @@ main (int argc, char **argv)
   char *vty_addr = NULL;
   int vty_port = OSPF_VTY_PORT;
   char vty_path[100];
+  char *vty_sock_name;
   int daemon_mode = 0;
   char *config_file = NULL;
   char *progname;
@@ -253,6 +260,9 @@ main (int argc, char **argv)
           if (vty_port <= 0 || vty_port > 0xffff)
             vty_port = OSPF_VTY_PORT;
          break;
+       case OPTION_VTYSOCK:
+         set_socket_path(vty_sock_path, OSPF_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+         break;
        case 'u':
          ospfd_privs.user = optarg;
          break;
@@ -357,19 +367,48 @@ main (int argc, char **argv)
       exit (1);
     }
 
+  /* Create PID file */
+  if (instance)
+    {
+      char pidfile_temp[100];
+
+      /* Override the single file with file including instance
+         number in case of multi-instance */
+      if (strrchr(pid_file, '/') != NULL)
+          /* cut of pid_file at last / char * to get directory */
+          *strrchr(pid_file, '/') = '\0';
+      else
+          /* pid_file contains no directory - should never happen, but deal with it anyway */
+          /* throw-away all pid_file and assume it's only the filename */
+          pid_file[0] = '\0';
+
+      snprintf(pidfile_temp, sizeof(pidfile_temp), "%s/ospfd-%d.pid", pid_file, instance );
+      strncpy(pid_file, pidfile_temp, sizeof(pid_file));
+    }
+  /* Process id file create. */
+  pid_output (pid_file);
+
   /* Create VTY socket */
   if (instance)
     {
-      sprintf(pid_file, "%s/ospfd-%d.pid", DAEMON_VTY_DIR, instance);
-      sprintf(vty_path, "%s/ospfd-%d.vty", DAEMON_VTY_DIR, instance);
+      /* Multi-Instance. Use only path section of vty_sock_path with new file incl instance */
+      if (strrchr(vty_sock_path, '/') != NULL)
+        {
+          /* cut of pid_file at last / char * to get directory */
+          *strrchr(vty_sock_path, '/') = '\0';
+        }
+      else
+        {
+          /* pid_file contains no directory - should never happen, but deal with it anyway */
+          /* throw-away all pid_file and assume it's only the filename */
+          vty_sock_path[0] = '\0';
+        }
+        snprintf(vty_path, sizeof(vty_path), "%s/ospfd-%d.vty", vty_sock_path, instance );
     }
   else
     {
-      strcpy(vty_path, OSPF_VTYSH_PATH);
+      strcpy(vty_path, vty_sock_path);
     }
-  /* Process id file create. */
-  pid_output (pid_file);
-
   vty_serv_sock (vty_addr, vty_port, vty_path);
 
   /* Print banner. */
index 29432ea230a2c75f5f6962cd65181b8d237709f3..1a3c8165e4656491667bc60a4eceab9f33a245d5 100644 (file)
@@ -52,18 +52,25 @@ extern struct host host;
 
 char config_default[] = SYSCONFDIR PIMD_DEFAULT_CONFIG;
 
+/* pimd options */
+#define OPTION_VTYSOCK 1000
 struct option longopts[] = {
   { "daemon",        no_argument,       NULL, 'd'},
   { "config_file",   required_argument, NULL, 'f'},
   { "pid_file",      required_argument, NULL, 'i'},
+  { "socket",        required_argument, NULL, 'z'},
   { "vty_addr",      required_argument, NULL, 'A'},
   { "vty_port",      required_argument, NULL, 'P'},
+  { "vty_socket",    required_argument, NULL, OPTION_VTYSOCK},
   { "version",       no_argument,       NULL, 'v'},
   { "debug_zclient", no_argument,       NULL, 'Z'},
   { "help",          no_argument,       NULL, 'h'},
   { 0 }
 };
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = PIM_VTYSH_PATH;
+
 /* pimd privileges */
 zebra_capabilities_t _caps_p [] = 
 {
@@ -103,6 +110,7 @@ Daemon which manages PIM.\n\n\
 -z, --socket         Set path of zebra socket\n\
 -A, --vty_addr       Set vty's bind address\n\
 -P, --vty_port       Set vty's port number\n\
+    --vty_socket     Override vty socket path\n\
 -v, --version        Print program version\n\
 "
 
@@ -125,6 +133,7 @@ Report bugs to %s\n", progname, PIMD_BUG_ADDRESS);
 int main(int argc, char** argv, char** envp) {
   char *p;
   char *vty_addr = NULL;
+  char *vty_sock_name;
   int vty_port = -1;
   int daemon_mode = 0;
   char *config_file = NULL;
@@ -172,6 +181,9 @@ int main(int argc, char** argv, char** envp) {
     case 'P':
       vty_port = atoi (optarg);
       break;
+    case OPTION_VTYSOCK:
+      set_socket_path(vty_sock_path, PIM_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+      break;
     case 'v':
       printf(PIMD_PROGNAME " version %s\n", PIMD_VERSION);
       print_version(progname);
@@ -238,7 +250,7 @@ int main(int argc, char** argv, char** envp) {
   /* Create pimd VTY socket */
   if (vty_port < 0)
     vty_port = PIMD_VTY_PORT;
-  vty_serv_sock(vty_addr, vty_port, PIM_VTYSH_PATH);
+  vty_serv_sock(vty_addr, vty_port, vty_sock_path);
 
   zlog_notice("Quagga %s " PIMD_PROGNAME " %s starting, VTY interface at port TCP %d",
              FRR_VERSION, PIMD_VERSION, vty_port);
index cfcb60168a05a0bda4158a96cb32bc9265e88133..e46f867952ad8088aa77555fe54375d0f716555b 100644 (file)
@@ -39,6 +39,7 @@
 #include "ripd/ripd.h"
 
 /* ripd options. */
+#define OPTION_VTYSOCK 1000
 static struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
@@ -49,6 +50,7 @@ static struct option longopts[] =
   { "dryrun",      no_argument,       NULL, 'C'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "vty_socket",  required_argument, NULL, OPTION_VTYSOCK},
   { "retain",      no_argument,       NULL, 'r'},
   { "user",        required_argument, NULL, 'u'},
   { "group",       required_argument, NULL, 'g'},
@@ -85,6 +87,9 @@ char *config_file = NULL;
 
 /* ripd program name */
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = RIP_VTYSH_PATH;
+
 /* Route retain mode flag. */
 int retain_mode = 0;
 
@@ -116,6 +121,7 @@ Daemon which manages RIP version 1 and 2.\n\n\
 -z, --socket       Set path of zebra socket\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
 -C, --dryrun       Check configuration for validity and exit\n\
 -r, --retain       When program terminates, retain added route by ripd.\n\
 -u, --user         User to run as\n\
@@ -142,7 +148,7 @@ sighup (void)
   vty_read_config (config_file, config_default);
 
   /* Create VTY's socket */
-  vty_serv_sock (vty_addr, vty_port, RIP_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Try to return to normal operation. */
 }
@@ -195,6 +201,7 @@ main (int argc, char **argv)
   int dryrun = 0;
   char *progname;
   struct thread thread;
+  char *vty_sock_name;
 
   /* Set umask before anything for security */
   umask (0027);
@@ -251,6 +258,9 @@ main (int argc, char **argv)
           if (vty_port <= 0 || vty_port > 0xffff)
             vty_port = RIP_VTY_PORT;
          break;
+       case OPTION_VTYSOCK:
+         set_socket_path(vty_sock_path, RIP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+         break;
        case 'r':
          retain_mode = 1;
          break;
@@ -311,7 +321,7 @@ main (int argc, char **argv)
   pid_output (pid_file);
 
   /* Create VTY's socket */
-  vty_serv_sock (vty_addr, vty_port, RIP_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Print banner. */
   zlog_notice ("RIPd %s starting: vty@%d", FRR_VERSION, vty_port);
index 14711a1a65e5b68795afa88a0d1e227b18771163..1677996eaafb616dbeb88894c91ba97e3626bd62 100644 (file)
@@ -44,6 +44,7 @@ char config_default[] = SYSCONFDIR RIPNG_DEFAULT_CONFIG;
 char *config_file = NULL;
 
 /* RIPngd options. */
+#define OPTION_VTYSOCK 1000
 struct option longopts[] = 
 {
   { "daemon",      no_argument,       NULL, 'd'},
@@ -54,6 +55,7 @@ struct option longopts[] =
   { "help",        no_argument,       NULL, 'h'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "vty_socket",  required_argument, NULL, OPTION_VTYSOCK},
   { "retain",      no_argument,       NULL, 'r'},
   { "user",        required_argument, NULL, 'u'},
   { "group",       required_argument, NULL, 'g'},
@@ -87,6 +89,9 @@ struct zebra_privs_t ripngd_privs =
 
 /* RIPngd program name */
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = RIPNG_VTYSH_PATH;
+
 /* Route retain mode flag. */
 int retain_mode = 0;
 
@@ -118,6 +123,7 @@ Daemon which manages RIPng.\n\n\
 -z, --socket       Set path of zebra socket\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\n\
+    --vty_socket   Override vty socket path\n\
 -r, --retain       When program terminates, retain added route by ripngd.\n\
 -u, --user         User to run as\n\
 -g, --group        Group to run as\n\
@@ -141,7 +147,7 @@ sighup (void)
   /* Reload config file. */
   vty_read_config (config_file, config_default);
   /* Create VTY's socket */
-  vty_serv_sock (vty_addr, vty_port, RIPNG_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Try to return to normal operation. */
 }
@@ -195,6 +201,7 @@ main (int argc, char **argv)
   char *progname;
   struct thread thread;
   int dryrun = 0;
+  char *vty_sock_name;
 
   /* Set umask before anything for security */
   umask (0027);
@@ -249,6 +256,9 @@ main (int argc, char **argv)
           if (vty_port <= 0 || vty_port > 0xffff)
             vty_port = RIPNG_VTY_PORT;
           break;
+       case OPTION_VTYSOCK:
+         set_socket_path(vty_sock_path, RIPNG_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+         break;
        case 'r':
          retain_mode = 1;
          break;
@@ -303,7 +313,7 @@ main (int argc, char **argv)
     }
 
   /* Create VTY socket */
-  vty_serv_sock (vty_addr, vty_port, RIPNG_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Process id file create. */
   pid_output (pid_file);
index 6d6fe613060db5ce9bf254fb6c216c6725798369..17f6bfa5a54263083e724093c5a731df54f679e3 100644 (file)
@@ -2898,13 +2898,34 @@ vtysh_connect (struct vtysh_client *vclient)
   int sock, len;
   struct sockaddr_un addr;
   struct stat s_stat;
+  char path[MAXPATHLEN];
+
+  if (vty_sock_path == NULL)
+    strlcpy (path, vclient->path, sizeof (path));
+  else {
+    /* Different path for VTY Socket specified
+       overriding the default path, but keep the filename */
+    strlcpy (path, vty_sock_path, sizeof (path));
+
+    if (strrchr (vclient->path, '/') != NULL)
+      strlcat (path, strrchr (vclient->path, '/'), sizeof (path));
+    else {
+      /*
+       * vclient->path configured as relative path during config? Should
+       * really never happen for sensible config
+       */
+      strlcat (path, "/", sizeof (path));
+      strlcat (path, vclient->path, sizeof (path));
+    }
+  }
+  path[sizeof(path)-1] = '\0';
 
   /* Stat socket to see if we have permission to access it. */
-  ret = stat (vclient->path, &s_stat);
+  ret = stat (path, &s_stat);
   if (ret < 0 && errno != ENOENT)
     {
       fprintf  (stderr, "vtysh_connect(%s): stat = %s\n", 
-               vclient->path, safe_strerror(errno)); 
+                path, safe_strerror(errno));
       exit(1);
     }
   
@@ -2913,7 +2934,7 @@ vtysh_connect (struct vtysh_client *vclient)
       if (! S_ISSOCK(s_stat.st_mode))
        {
          fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
-                  vclient->path);
+                  path);
          exit (1);
        }
       
@@ -2923,7 +2944,7 @@ vtysh_connect (struct vtysh_client *vclient)
   if (sock < 0)
     {
 #ifdef DEBUG
-      fprintf(stderr, "vtysh_connect(%s): socket = %s\n", vclient->path,
+      fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path,
              safe_strerror(errno));
 #endif /* DEBUG */
       return -1;
@@ -2931,7 +2952,7 @@ vtysh_connect (struct vtysh_client *vclient)
 
   memset (&addr, 0, sizeof (struct sockaddr_un));
   addr.sun_family = AF_UNIX;
-  strncpy (addr.sun_path, vclient->path, strlen (vclient->path));
+  strncpy (addr.sun_path, path, strlen (path));
 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
   len = addr.sun_len = SUN_LEN(&addr);
 #else
@@ -2942,7 +2963,7 @@ vtysh_connect (struct vtysh_client *vclient)
   if (ret < 0)
     {
 #ifdef DEBUG
-      fprintf(stderr, "vtysh_connect(%s): connect = %s\n", vclient->path,
+      fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path,
              safe_strerror(errno));
 #endif /* DEBUG */
       close (sock);
@@ -2993,14 +3014,23 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
 {
   struct vtysh_client *client;
   char *ptr;
+  char vty_dir[MAXPATHLEN];
   DIR *dir;
   struct dirent *file;
   int n = 0;
 
   if (head_client->flag != VTYSH_OSPFD) return;
 
-  /* ls DAEMON_VTY_DIR and look for all files ending in .vty */
-  dir = opendir(DAEMON_VTY_DIR "/");
+  if (vty_sock_path == NULL)
+    /* ls DAEMON_VTY_DIR and look for all files ending in .vty */
+    strlcpy(vty_dir, DAEMON_VTY_DIR "/", MAXPATHLEN);
+  else
+    {
+    /* ls vty_sock_dir and look for all files ending in .vty */
+    strlcpy(vty_dir, vty_sock_path, MAXPATHLEN);
+    strlcat(vty_dir, "/", MAXPATHLEN);
+    }
+  dir = opendir(vty_dir);
   if (dir)
     {
       while ((file = readdir(dir)) != NULL)
@@ -3010,8 +3040,8 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
               if (n == MAXIMUM_INSTANCES)
                 {
                   fprintf(stderr,
-                          "Parsing %s/, client limit(%d) reached!\n",
-                          DAEMON_VTY_DIR, n);
+                          "Parsing %s, client limit(%d) reached!\n",
+                          vty_dir, n);
                   break;
                 }
               client = (struct vtysh_client *) malloc(sizeof(struct vtysh_client));
@@ -3019,7 +3049,7 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
              client->name = "ospfd";
               client->flag = VTYSH_OSPFD;
               ptr = (char *) malloc(100);
-              sprintf(ptr, "%s/%s", DAEMON_VTY_DIR, file->d_name);
+              sprintf(ptr, "%s%s", vty_dir, file->d_name);
              client->path = (const char *)ptr;
               client->next = NULL;
               vtysh_client_sorted_insert(head_client, client);
index 46ed0019193b53abc77f1e916f1fdf33e09ae807..537f944a7a0451f3c9e666c2233a866089144c17 100644 (file)
@@ -96,4 +96,6 @@ extern int execute_flag;
 
 extern struct vty *vty;
 
+extern char * vty_sock_path;
+
 #endif /* VTYSH_H */
index 6b33fca39b6a2a632f35aa2cd86f7bac84df9edc..bad21ae6614d96be8536a1606cc3ee12c85bbbe8 100644 (file)
 char *progname;
 
 /* Configuration file name and directory. */
-static char vtysh_config_always[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
-static char quagga_config_default[] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG;
+static char vtysh_config_always[MAXPATHLEN] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
+static char quagga_config_default[MAXPATHLEN] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG;
 char *quagga_config = quagga_config_default;
 char history_file[MAXPATHLEN];
 
 /* Flag for indicate executing child command. */
 int execute_flag = 0;
 
+/* VTY Socket prefix */
+char * vty_sock_path = NULL;
+
 /* For sigsetjmp() & siglongjmp(). */
 static sigjmp_buf jmpbuf;
 
@@ -144,8 +147,11 @@ usage (int status)
            "-f, --inputfile          Execute commands from specific file and exit\n" \
            "-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"
+           "    --vty_socket         Override vty socket path\n" \
+           "-m, --markfile           Mark input file with context end\n" \
+           "    --vty_socket         Override vty socket path\n" \
+           "    --config_dir         Override config directory path\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" \
@@ -156,6 +162,8 @@ usage (int status)
 }
 
 /* VTY shell options, we use GNU getopt library. */
+#define OPTION_VTYSOCK 1000
+#define OPTION_CONFDIR 1001
 struct option longopts[] = 
 {
   { "boot",                 no_argument,             NULL, 'b'},
@@ -163,6 +171,8 @@ struct option longopts[] =
   { "eval",                 required_argument,       NULL, 'e'},
   { "command",              required_argument,       NULL, 'c'},
   { "daemon",               required_argument,       NULL, 'd'},
+  { "vty_socket",           required_argument,       NULL, OPTION_VTYSOCK},
+  { "config_dir",           required_argument,       NULL, OPTION_CONFDIR},
   { "inputfile",            required_argument,       NULL, 'f'},
   { "echo",                 no_argument,             NULL, 'E'},
   { "dryrun",              no_argument,             NULL, 'C'},
@@ -262,6 +272,7 @@ main (int argc, char **argv, char **env)
   int boot_flag = 0;
   const char *daemon_name = NULL;
   const char *inputfile = NULL;
+  char *vtysh_configfile_name;
   struct cmd_rec {
     const char *line;
     struct cmd_rec *next;
@@ -274,6 +285,9 @@ main (int argc, char **argv, char **env)
   int ret = 0;
   char *homedir = NULL;
 
+  /* check for restricted functionality if vtysh is run setuid */
+  int restricted = (getuid() != geteuid()) || (getgid() != getegid());
+
   /* Preserve name of myself. */
   progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
 
@@ -310,6 +324,55 @@ main (int argc, char **argv, char **env)
            tail = cr;
          }
          break;
+       case OPTION_VTYSOCK:
+         vty_sock_path = optarg;
+         break;
+       case OPTION_CONFDIR:
+      /* 
+       * Skip option for Config Directory if setuid
+       */
+      if (restricted) 
+        {
+          fprintf (stderr, "Overriding of Config Directory blocked for vtysh with setuid");
+          return 1;
+        }
+         /* 
+          * Overwrite location for vtysh.conf
+          */
+         vtysh_configfile_name = strrchr(VTYSH_DEFAULT_CONFIG, '/');
+         if (vtysh_configfile_name)
+           /* skip '/' */
+           vtysh_configfile_name++;
+         else
+           /*
+            * VTYSH_DEFAULT_CONFIG configured with relative path
+            * during config? Should really never happen for
+            * sensible config
+            */
+           vtysh_configfile_name = (char *) VTYSH_DEFAULT_CONFIG;
+         strlcpy(vtysh_config_always, optarg, sizeof(vtysh_config_always));
+         strlcat(vtysh_config_always, "/", sizeof(vtysh_config_always));
+         strlcat(vtysh_config_always, vtysh_configfile_name, 
+             sizeof(vtysh_config_always));
+         /* 
+          * Overwrite location for Quagga.conf
+          */
+         vtysh_configfile_name = strrchr(QUAGGA_DEFAULT_CONFIG, '/');
+         if (vtysh_configfile_name)
+           /* skip '/' */
+           vtysh_configfile_name++;
+         else
+           /*
+            * QUAGGA_DEFAULT_CONFIG configured with relative path
+            * during config? Should really never happen for
+            * sensible config
+            */
+           vtysh_configfile_name = (char *) QUAGGA_DEFAULT_CONFIG;
+         strlcpy(quagga_config_default, optarg, sizeof(vtysh_config_always));
+         strlcat(quagga_config_default, "/", sizeof(vtysh_config_always));
+         strlcat(quagga_config_default, vtysh_configfile_name, 
+             sizeof(quagga_config_default));
+         break;
        case 'd':
          daemon_name = optarg;
          break;
index 3a64ae0a966e9ca93867e2a8f7b8377a3c6200e6..73f7c1be980a2d579de9659564f166e77cce374c 100644 (file)
@@ -218,7 +218,12 @@ char *
 vtysh_get_home (void)
 {
   struct passwd *passwd;
+  char * homedir;
 
+  if ((homedir = getenv("HOME")) != 0)
+    return homedir;
+
+  /* Fallback if HOME is undefined */
   passwd = getpwuid (getuid ());
 
   return passwd ? passwd->pw_dir : NULL;
index 9abc8f87ffd43e41b0a29df47da324a9a9b38046..aa1cbc3b267a887c931800c98059f59dffb88f09 100644 (file)
@@ -59,6 +59,9 @@ struct zebra_t zebrad =
 /* process id. */
 pid_t pid;
 
+/* VTY Socket prefix */
+char vty_sock_path[MAXPATHLEN] = ZEBRA_VTYSH_PATH;
+
 /* Pacify zclient.o in libzebra, which expects this variable. */
 struct thread_master *master;
 
@@ -77,6 +80,7 @@ u_int32_t nl_rcvbufsize = 4194304;
 #endif /* HAVE_NETLINK */
 
 /* Command line options. */
+#define OPTION_VTYSOCK 1000
 struct option longopts[] = 
 {
   { "batch",        no_argument,       NULL, 'b'},
@@ -90,6 +94,7 @@ struct option longopts[] =
   { "help",         no_argument,       NULL, 'h'},
   { "vty_addr",     required_argument, NULL, 'A'},
   { "vty_port",     required_argument, NULL, 'P'},
+  { "vty_socket",   required_argument, NULL, OPTION_VTYSOCK },
   { "retain",       no_argument,       NULL, 'r'},
   { "dryrun",       no_argument,       NULL, 'C'},
 #ifdef HAVE_NETLINK
@@ -152,6 +157,7 @@ usage (char *progname, int status)
              "-C, --dryrun       Check configuration for validity and exit\n"\
              "-A, --vty_addr     Set vty's bind address\n"\
              "-P, --vty_port     Set vty's port number\n"\
+             "    --vty_socket   Override vty socket path\n"\
              "-r, --retain       When program terminates, retain added route "\
                                  "by zebra.\n"\
              "-u, --user         User to run as\n"\
@@ -259,6 +265,7 @@ main (int argc, char **argv)
   char *p;
   char *vty_addr = NULL;
   int vty_port = ZEBRA_VTY_PORT;
+  char *vty_sock_name;
   int dryrun = 0;
   int batch_mode = 0;
   int daemon_mode = 0;
@@ -339,6 +346,9 @@ main (int argc, char **argv)
          if (vty_port <= 0 || vty_port > 0xffff)
            vty_port = ZEBRA_VTY_PORT;
          break;
+       case OPTION_VTYSOCK:
+         set_socket_path(vty_sock_path, ZEBRA_VTYSH_PATH, optarg, sizeof (vty_sock_path));
+         break;
        case 'r':
          retain_mode = 1;
          break;
@@ -463,7 +473,7 @@ main (int argc, char **argv)
   zebra_zserv_socket_init (zserv_path);
 
   /* Make vty server socket. */
-  vty_serv_sock (vty_addr, vty_port, ZEBRA_VTYSH_PATH);
+  vty_serv_sock (vty_addr, vty_port, vty_sock_path);
 
   /* Print banner. */
   zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, vty_port);