Merge pull request #120 from opensourcerouting/snapcraft-base-v3

Snapcraft base changes
This commit is contained in:
Russ White 2017-01-25 15:04:49 -05:00 committed by GitHub
commit dfa7df29a8
22 changed files with 349 additions and 59 deletions

View File

@ -59,6 +59,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#endif #endif
/* bgpd options, we use GNU getopt library. */ /* bgpd options, we use GNU getopt library. */
#define OPTION_VTYSOCK 1000
static const struct option longopts[] = static const struct option longopts[] =
{ {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
@ -69,6 +70,7 @@ static const struct option longopts[] =
{ "listenon", required_argument, NULL, 'l'}, { "listenon", required_argument, NULL, 'l'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "no_kernel", no_argument, NULL, 'n'}, { "no_kernel", no_argument, NULL, 'n'},
{ "user", required_argument, NULL, 'u'}, { "user", required_argument, NULL, 'u'},
@ -111,6 +113,9 @@ static struct quagga_signal_t bgp_signals[] =
/* Configuration file and directory. */ /* Configuration file and directory. */
char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG; char config_default[] = SYSCONFDIR BGP_DEFAULT_CONFIG;
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = BGP_VTYSH_PATH;
/* Route retain mode flag. */ /* Route retain mode flag. */
static int retain_mode = 0; static int retain_mode = 0;
@ -123,6 +128,7 @@ static const char *pid_file = PATH_BGPD_PID;
/* VTY port number and address. */ /* VTY port number and address. */
int vty_port = BGP_VTY_PORT; int vty_port = BGP_VTY_PORT;
char *vty_addr = NULL; char *vty_addr = NULL;
char *vty_sock_name;
/* privileges */ /* privileges */
static zebra_capabilities_t _caps_p [] = 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\ -l, --listenon Listen on specified address (implies -n)\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\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\ -r, --retain When program terminates, retain added route by bgpd.\n\
-n, --no_kernel Do not install route to kernel.\n\ -n, --no_kernel Do not install route to kernel.\n\
-u, --user User to run as\n\ -u, --user User to run as\n\
@ -195,7 +202,7 @@ sighup (void)
vty_read_config (config_file, config_default); vty_read_config (config_file, config_default);
/* Create VTY's socket */ /* 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. */ /* Try to return to normal operation. */
} }
@ -469,6 +476,9 @@ main (int argc, char **argv)
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = BGP_VTY_PORT; vty_port = BGP_VTY_PORT;
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, BGP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
@ -544,7 +554,7 @@ main (int argc, char **argv)
pid_output (pid_file); pid_output (pid_file);
/* Make bgp vty socket. */ /* 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. */ /* Print banner. */
zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", FRR_COPYRIGHT, zlog_notice ("BGPd %s starting: vty@%d, bgp@%s:%d", FRR_COPYRIGHT,

View File

@ -81,6 +81,7 @@ struct zebra_privs_t isisd_privs = {
}; };
/* isisd options */ /* isisd options */
#define OPTION_VTYSOCK 1000
struct option longopts[] = { struct option longopts[] = {
{"daemon", no_argument, NULL, 'd'}, {"daemon", no_argument, NULL, 'd'},
{"config_file", required_argument, NULL, 'f'}, {"config_file", required_argument, NULL, 'f'},
@ -88,6 +89,7 @@ struct option longopts[] = {
{"socket", required_argument, NULL, 'z'}, {"socket", required_argument, NULL, 'z'},
{"vty_addr", required_argument, NULL, 'A'}, {"vty_addr", required_argument, NULL, 'A'},
{"vty_port", required_argument, NULL, 'P'}, {"vty_port", required_argument, NULL, 'P'},
{"vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{"user", required_argument, NULL, 'u'}, {"user", required_argument, NULL, 'u'},
{"group", required_argument, NULL, 'g'}, {"group", required_argument, NULL, 'g'},
{"version", no_argument, NULL, 'v'}, {"version", no_argument, NULL, 'v'},
@ -103,6 +105,9 @@ char *config_file = NULL;
/* isisd program name. */ /* isisd program name. */
char *progname; char *progname;
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = ISIS_VTYSH_PATH;
int daemon_mode = 0; int daemon_mode = 0;
/* Master of threads. */ /* Master of threads. */
@ -144,6 +149,7 @@ Daemon which manages IS-IS routing\n\n\
-z, --socket Set path of zebra socket\n\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
--vty_socket Override vty socket path\n\
-u, --user User to run as\n\ -u, --user User to run as\n\
-g, --group Group to run as\n\ -g, --group Group to run as\n\
-v, --version Print program version\n\ -v, --version Print program version\n\
@ -240,6 +246,7 @@ main (int argc, char **argv, char **envp)
struct thread thread; struct thread thread;
char *config_file = NULL; char *config_file = NULL;
char *vty_addr = NULL; char *vty_addr = NULL;
char *vty_sock_name;
int dryrun = 0; int dryrun = 0;
/* Get the programname without the preceding path. */ /* Get the programname without the preceding path. */
@ -305,6 +312,9 @@ main (int argc, char **argv, char **envp)
vty_port = atoi (optarg); vty_port = atoi (optarg);
vty_port = (vty_port ? vty_port : ISISD_VTY_PORT); vty_port = (vty_port ? vty_port : ISISD_VTY_PORT);
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, ISIS_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'u': case 'u':
isisd_privs.user = optarg; isisd_privs.user = optarg;
break; break;
@ -379,7 +389,7 @@ main (int argc, char **argv, char **envp)
pid_output (pid_file); pid_output (pid_file);
/* Make isis vty socket. */ /* 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. */ /* Print banner. */
zlog_notice ("Quagga-ISISd %s starting: vty@%d", FRR_VERSION, vty_port); zlog_notice ("Quagga-ISISd %s starting: vty@%d", FRR_VERSION, vty_port);

View File

@ -51,28 +51,28 @@ control_init(void)
memset(&s_un, 0, sizeof(s_un)); memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX; 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) { if (errno != ENOENT) {
log_warn("%s: unlink %s", __func__, LDPD_SOCKET); log_warn("%s: unlink %s", __func__, ctl_sock_path);
close(fd); close(fd);
return (-1); return (-1);
} }
old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) { 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); close(fd);
umask(old_umask); umask(old_umask);
return (-1); return (-1);
} }
umask(old_umask); 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__); log_warn("%s: chmod", __func__);
close(fd); close(fd);
(void)unlink(LDPD_SOCKET); (void)unlink(ctl_sock_path);
return (-1); return (-1);
} }
@ -97,7 +97,7 @@ control_cleanup(void)
{ {
accept_del(control_fd); accept_del(control_fd);
close(control_fd); close(control_fd);
unlink(LDPD_SOCKET); unlink(ctl_sock_path);
} }
/* ARGSUSED */ /* ARGSUSED */

View File

@ -405,9 +405,9 @@ ldp_vty_connect(struct imsgbuf *ibuf)
memset(&s_un, 0, sizeof(s_un)); memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX; 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) { 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); close(ctl_sock);
return (-1); return (-1);
} }

View File

@ -43,7 +43,7 @@
static void ldpd_shutdown(void); static void ldpd_shutdown(void);
static pid_t start_child(enum ldpd_process, char *, int, 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_ldpe(struct thread *);
static int main_dispatch_lde(struct thread *); static int main_dispatch_lde(struct thread *);
static int main_imsg_send_ipc_sockets(struct imsgbuf *, static int main_imsg_send_ipc_sockets(struct imsgbuf *,
@ -115,7 +115,15 @@ struct zebra_privs_t ldpd_privs =
.cap_num_i = 0 .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. */ /* LDPd options. */
#define OPTION_VTYSOCK 1000
#define OPTION_CTLSOCK 1001
static struct option longopts[] = static struct option longopts[] =
{ {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
@ -126,6 +134,8 @@ static struct option longopts[] =
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "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'}, { "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'}, { "group", required_argument, NULL, 'g'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
@ -148,6 +158,8 @@ Daemon which manages LDP.\n\n\
-z, --socket Set path of zebra socket\n\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\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\ -u, --user User to run as\n\
-g, --group Group to run as\n\ -g, --group Group to run as\n\
-v, --version Print program version\n\ -v, --version Print program version\n\
@ -212,6 +224,9 @@ main(int argc, char *argv[])
char *p; char *p;
char *vty_addr = NULL; char *vty_addr = NULL;
int vty_port = LDP_VTY_PORT; int vty_port = LDP_VTY_PORT;
char *vty_sock_name;
char *ctl_sock_custom_path = NULL;
char *ctl_sock_name;
int daemon_mode = 0; int daemon_mode = 0;
const char *user = NULL; const char *user = NULL;
const char *group = NULL; const char *group = NULL;
@ -272,6 +287,28 @@ main(int argc, char *argv[])
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = LDP_VTY_PORT; vty_port = LDP_VTY_PORT;
break; 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': case 'u':
user = optarg; user = optarg;
break; break;
@ -318,7 +355,7 @@ main(int argc, char *argv[])
if (lflag) if (lflag)
lde(user, group); lde(user, group);
else if (eflag) else if (eflag)
ldpe(user, group); ldpe(user, group, ctl_sock_path);
master = thread_master_create(); master = thread_master_create();
@ -360,9 +397,9 @@ main(int argc, char *argv[])
/* start children */ /* start children */
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0, 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, 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 */ /* drop privileges */
if (user) if (user)
@ -410,7 +447,7 @@ main(int argc, char *argv[])
pid_output(pid_file); pid_output(pid_file);
/* Create VTY socket */ /* 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. */ /* Print banner. */
log_notice("LDPd %s starting: vty@%d", FRR_VERSION, vty_port); log_notice("LDPd %s starting: vty@%d", FRR_VERSION, vty_port);
@ -458,9 +495,9 @@ ldpd_shutdown(void)
static pid_t static pid_t
start_child(enum ldpd_process p, char *argv0, int fd, const char *user, 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; int argc = 0;
pid_t pid; 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 *)"-g";
argv[argc++] = (char *)group; argv[argc++] = (char *)group;
} }
if (ctl_sock_custom_path) {
argv[argc++] = (char *)"--ctl_socket";
argv[argc++] = (char *)ctl_sock_custom_path;
}
argv[argc++] = NULL; argv[argc++] = NULL;
execvp(argv0, argv); execvp(argv0, argv);

View File

@ -672,6 +672,7 @@ int sock_set_ipv6_mcast_loop(int);
/* quagga */ /* quagga */
extern struct thread_master *master; extern struct thread_master *master;
extern char ctl_sock_path[MAXPATHLEN];
/* ldp_zebra.c */ /* ldp_zebra.c */
void ldp_zebra_init(struct thread_master *); void ldp_zebra_init(struct thread_master *);

View File

@ -99,7 +99,7 @@ static struct quagga_signal_t ldpe_signals[] =
/* label distribution protocol engine */ /* label distribution protocol engine */
void void
ldpe(const char *user, const char *group) ldpe(const char *user, const char *group, const char *ctl_path)
{ {
struct thread thread; struct thread thread;
@ -128,6 +128,7 @@ ldpe(const char *user, const char *group)
ldpe_privs.group = group; ldpe_privs.group = group;
zprivs_init(&ldpe_privs); zprivs_init(&ldpe_privs);
strlcpy(ctl_sock_path, ctl_path, sizeof(ctl_sock_path));
if (control_init() == -1) if (control_init() == -1)
fatalx("control socket setup failed"); fatalx("control socket setup failed");

View File

@ -183,7 +183,7 @@ int tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
uint16_t, struct map *); uint16_t, struct map *);
/* ldpe.c */ /* 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 *, int ldpe_imsg_compose_parent(int, pid_t, void *,
uint16_t); uint16_t);
int ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *, int ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,

View 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 */ /* 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) ) 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 /* we have caps, we have no need to ever change back the original user
* change real, effective and saved to the specified 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) ) if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
{ {
@ -602,7 +604,8 @@ zprivs_caps_terminate (void)
int int
zprivs_change_uid (zebra_privs_ops_t op) zprivs_change_uid (zebra_privs_ops_t op)
{ {
if (zprivs_state.zsuid == zprivs_state.zuid)
return 0;
if (op == ZPRIVS_RAISE) if (op == ZPRIVS_RAISE)
return seteuid (zprivs_state.zsuid); return seteuid (zprivs_state.zsuid);
else if (op == ZPRIVS_LOWER) 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) ) 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 */ /* change group now, forever. uid we do later */
if ( setregid (zprivs_state.zgid, zprivs_state.zgid) ) 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. * This is not worth that much security wise, but all we can do.
*/ */
zprivs_state.zsuid = geteuid(); 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) ) if ( setreuid (-1, zprivs_state.zuid) )
{ {
@ -824,7 +830,8 @@ zprivs_terminate (struct zebra_privs_t *zprivs)
#ifdef HAVE_CAPABILITIES #ifdef HAVE_CAPABILITIES
zprivs_caps_terminate(); zprivs_caps_terminate();
#else /* !HAVE_CAPABILITIES */ #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) ) if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) )
{ {

View File

@ -29,6 +29,29 @@
#include "sockopt.h" #include "sockopt.h"
#include "sockunion.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 void
setsockopt_so_recvbuf (int sock, int size) setsockopt_so_recvbuf (int sock, int size)
{ {

View File

@ -24,6 +24,9 @@
#include "sockunion.h" #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_recvbuf (int sock, int size);
extern void setsockopt_so_sendbuf (const int sock, int size); extern void setsockopt_so_sendbuf (const int sock, int size);
extern int getsockopt_so_sendbuf (const int sock); extern int getsockopt_so_sendbuf (const int sock);

View File

@ -2091,8 +2091,11 @@ vty_serv_un (const char *path)
umask (old_mask); umask (old_mask);
zprivs_get_ids(&ids); 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 */ /* set group of socket */
if ( chown (path, -1, ids.gid_vty) ) if ( chown (path, -1, ids.gid_vty) )

View File

@ -51,6 +51,9 @@
/* Default configuration file name for ospf6d. */ /* Default configuration file name for ospf6d. */
#define OSPF6_DEFAULT_CONFIG "ospf6d.conf" #define OSPF6_DEFAULT_CONFIG "ospf6d.conf"
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = OSPF6_VTYSH_PATH;
/* Default port values. */ /* Default port values. */
#define OSPF6_VTY_PORT 2606 #define OSPF6_VTY_PORT 2606
@ -78,6 +81,7 @@ struct zebra_privs_t ospf6d_privs =
}; };
/* ospf6d options, we use GNU getopt library. */ /* ospf6d options, we use GNU getopt library. */
#define OPTION_VTYSOCK 1000
struct option longopts[] = struct option longopts[] =
{ {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
@ -86,6 +90,7 @@ struct option longopts[] =
{ "socket", required_argument, NULL, 'z'}, { "socket", required_argument, NULL, 'z'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "user", required_argument, NULL, 'u'}, { "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'}, { "group", required_argument, NULL, 'g'},
{ "version", no_argument, NULL, 'v'}, { "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\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
--vty_socket Override vty socket path\n\
-u, --user User to run as\n\ -u, --user User to run as\n\
-g, --group Group to run as\n\ -g, --group Group to run as\n\
-v, --version Print program version\n\ -v, --version Print program version\n\
@ -233,6 +239,7 @@ main (int argc, char *argv[], char *envp[])
int opt; int opt;
char *vty_addr = NULL; char *vty_addr = NULL;
int vty_port = 0; int vty_port = 0;
char *vty_sock_name;
char *config_file = NULL; char *config_file = NULL;
struct thread thread; struct thread thread;
int dryrun = 0; int dryrun = 0;
@ -285,6 +292,9 @@ main (int argc, char *argv[], char *envp[])
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = OSPF6_VTY_PORT; vty_port = OSPF6_VTY_PORT;
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, OSPF6_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'u': case 'u':
ospf6d_privs.user = optarg; ospf6d_privs.user = optarg;
break; break;
@ -357,7 +367,7 @@ main (int argc, char *argv[], char *envp[])
/* Make ospf6 vty socket. */ /* Make ospf6 vty socket. */
if (!vty_port) if (!vty_port)
vty_port = OSPF6_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 */ /* Print start message */
zlog_notice ("OSPF6d (Quagga-%s ospf6d-%s) starts: vty@%d", zlog_notice ("OSPF6d (Quagga-%s ospf6d-%s) starts: vty@%d",

View File

@ -79,6 +79,7 @@ struct zebra_privs_t ospfd_privs =
char config_default[100]; char config_default[100];
/* OSPFd options. */ /* OSPFd options. */
#define OPTION_VTYSOCK 1000
struct option longopts[] = struct option longopts[] =
{ {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
@ -90,6 +91,7 @@ struct option longopts[] =
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "user", required_argument, NULL, 'u'}, { "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'}, { "group", required_argument, NULL, 'g'},
{ "apiserver", no_argument, NULL, 'a'}, { "apiserver", no_argument, NULL, 'a'},
@ -99,6 +101,9 @@ struct option longopts[] =
/* OSPFd program name */ /* OSPFd program name */
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = OSPF_VTYSH_PATH;
/* Master of threads. */ /* Master of threads. */
struct thread_master *master; struct thread_master *master;
@ -126,6 +131,7 @@ Daemon which manages OSPF.\n\n\
-z, --socket Set path of zebra socket\n\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
--vty_socket Override vty socket path\n\
-u, --user User to run as\n\ -u, --user User to run as\n\
-g, --group Group to run as\n\ -g, --group Group to run as\n\
-a. --apiserver Enable OSPF apiserver\n\ -a. --apiserver Enable OSPF apiserver\n\
@ -188,6 +194,7 @@ main (int argc, char **argv)
char *vty_addr = NULL; char *vty_addr = NULL;
int vty_port = OSPF_VTY_PORT; int vty_port = OSPF_VTY_PORT;
char vty_path[100]; char vty_path[100];
char *vty_sock_name;
int daemon_mode = 0; int daemon_mode = 0;
char *config_file = NULL; char *config_file = NULL;
char *progname; char *progname;
@ -253,6 +260,9 @@ main (int argc, char **argv)
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = OSPF_VTY_PORT; vty_port = OSPF_VTY_PORT;
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, OSPF_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'u': case 'u':
ospfd_privs.user = optarg; ospfd_privs.user = optarg;
break; break;
@ -357,19 +367,48 @@ main (int argc, char **argv)
exit (1); exit (1);
} }
/* Create VTY socket */ /* Create PID file */
if (instance) if (instance)
{ {
sprintf(pid_file, "%s/ospfd-%d.pid", DAEMON_VTY_DIR, instance); char pidfile_temp[100];
sprintf(vty_path, "%s/ospfd-%d.vty", DAEMON_VTY_DIR, instance);
} /* Override the single file with file including instance
else number in case of multi-instance */
{ if (strrchr(pid_file, '/') != NULL)
strcpy(vty_path, OSPF_VTYSH_PATH); /* 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. */ /* Process id file create. */
pid_output (pid_file); pid_output (pid_file);
/* Create VTY socket */
if (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, vty_sock_path);
}
vty_serv_sock (vty_addr, vty_port, vty_path); vty_serv_sock (vty_addr, vty_port, vty_path);
/* Print banner. */ /* Print banner. */

View File

@ -52,18 +52,25 @@ extern struct host host;
char config_default[] = SYSCONFDIR PIMD_DEFAULT_CONFIG; char config_default[] = SYSCONFDIR PIMD_DEFAULT_CONFIG;
/* pimd options */
#define OPTION_VTYSOCK 1000
struct option longopts[] = { struct option longopts[] = {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
{ "config_file", required_argument, NULL, 'f'}, { "config_file", required_argument, NULL, 'f'},
{ "pid_file", required_argument, NULL, 'i'}, { "pid_file", required_argument, NULL, 'i'},
{ "socket", required_argument, NULL, 'z'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ "debug_zclient", no_argument, NULL, 'Z'}, { "debug_zclient", no_argument, NULL, 'Z'},
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ 0 } { 0 }
}; };
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = PIM_VTYSH_PATH;
/* pimd privileges */ /* pimd privileges */
zebra_capabilities_t _caps_p [] = zebra_capabilities_t _caps_p [] =
{ {
@ -103,6 +110,7 @@ Daemon which manages PIM.\n\n\
-z, --socket Set path of zebra socket\n\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
--vty_socket Override vty socket path\n\
-v, --version Print program version\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) { int main(int argc, char** argv, char** envp) {
char *p; char *p;
char *vty_addr = NULL; char *vty_addr = NULL;
char *vty_sock_name;
int vty_port = -1; int vty_port = -1;
int daemon_mode = 0; int daemon_mode = 0;
char *config_file = NULL; char *config_file = NULL;
@ -172,6 +181,9 @@ int main(int argc, char** argv, char** envp) {
case 'P': case 'P':
vty_port = atoi (optarg); vty_port = atoi (optarg);
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, PIM_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'v': case 'v':
printf(PIMD_PROGNAME " version %s\n", PIMD_VERSION); printf(PIMD_PROGNAME " version %s\n", PIMD_VERSION);
print_version(progname); print_version(progname);
@ -238,7 +250,7 @@ int main(int argc, char** argv, char** envp) {
/* Create pimd VTY socket */ /* Create pimd VTY socket */
if (vty_port < 0) if (vty_port < 0)
vty_port = PIMD_VTY_PORT; 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", zlog_notice("Quagga %s " PIMD_PROGNAME " %s starting, VTY interface at port TCP %d",
FRR_VERSION, PIMD_VERSION, vty_port); FRR_VERSION, PIMD_VERSION, vty_port);

View File

@ -39,6 +39,7 @@
#include "ripd/ripd.h" #include "ripd/ripd.h"
/* ripd options. */ /* ripd options. */
#define OPTION_VTYSOCK 1000
static struct option longopts[] = static struct option longopts[] =
{ {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
@ -49,6 +50,7 @@ static struct option longopts[] =
{ "dryrun", no_argument, NULL, 'C'}, { "dryrun", no_argument, NULL, 'C'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "user", required_argument, NULL, 'u'}, { "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'}, { "group", required_argument, NULL, 'g'},
@ -85,6 +87,9 @@ char *config_file = NULL;
/* ripd program name */ /* ripd program name */
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = RIP_VTYSH_PATH;
/* Route retain mode flag. */ /* Route retain mode flag. */
int retain_mode = 0; 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\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\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\ -C, --dryrun Check configuration for validity and exit\n\
-r, --retain When program terminates, retain added route by ripd.\n\ -r, --retain When program terminates, retain added route by ripd.\n\
-u, --user User to run as\n\ -u, --user User to run as\n\
@ -142,7 +148,7 @@ sighup (void)
vty_read_config (config_file, config_default); vty_read_config (config_file, config_default);
/* Create VTY's socket */ /* 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. */ /* Try to return to normal operation. */
} }
@ -195,6 +201,7 @@ main (int argc, char **argv)
int dryrun = 0; int dryrun = 0;
char *progname; char *progname;
struct thread thread; struct thread thread;
char *vty_sock_name;
/* Set umask before anything for security */ /* Set umask before anything for security */
umask (0027); umask (0027);
@ -251,6 +258,9 @@ main (int argc, char **argv)
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = RIP_VTY_PORT; vty_port = RIP_VTY_PORT;
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, RIP_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
@ -311,7 +321,7 @@ main (int argc, char **argv)
pid_output (pid_file); pid_output (pid_file);
/* Create VTY's socket */ /* 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. */ /* Print banner. */
zlog_notice ("RIPd %s starting: vty@%d", FRR_VERSION, vty_port); zlog_notice ("RIPd %s starting: vty@%d", FRR_VERSION, vty_port);

View File

@ -44,6 +44,7 @@ char config_default[] = SYSCONFDIR RIPNG_DEFAULT_CONFIG;
char *config_file = NULL; char *config_file = NULL;
/* RIPngd options. */ /* RIPngd options. */
#define OPTION_VTYSOCK 1000
struct option longopts[] = struct option longopts[] =
{ {
{ "daemon", no_argument, NULL, 'd'}, { "daemon", no_argument, NULL, 'd'},
@ -54,6 +55,7 @@ struct option longopts[] =
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "user", required_argument, NULL, 'u'}, { "user", required_argument, NULL, 'u'},
{ "group", required_argument, NULL, 'g'}, { "group", required_argument, NULL, 'g'},
@ -87,6 +89,9 @@ struct zebra_privs_t ripngd_privs =
/* RIPngd program name */ /* RIPngd program name */
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = RIPNG_VTYSH_PATH;
/* Route retain mode flag. */ /* Route retain mode flag. */
int retain_mode = 0; int retain_mode = 0;
@ -118,6 +123,7 @@ Daemon which manages RIPng.\n\n\
-z, --socket Set path of zebra socket\n\ -z, --socket Set path of zebra socket\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\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\ -r, --retain When program terminates, retain added route by ripngd.\n\
-u, --user User to run as\n\ -u, --user User to run as\n\
-g, --group Group to run as\n\ -g, --group Group to run as\n\
@ -141,7 +147,7 @@ sighup (void)
/* Reload config file. */ /* Reload config file. */
vty_read_config (config_file, config_default); vty_read_config (config_file, config_default);
/* Create VTY's socket */ /* 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. */ /* Try to return to normal operation. */
} }
@ -195,6 +201,7 @@ main (int argc, char **argv)
char *progname; char *progname;
struct thread thread; struct thread thread;
int dryrun = 0; int dryrun = 0;
char *vty_sock_name;
/* Set umask before anything for security */ /* Set umask before anything for security */
umask (0027); umask (0027);
@ -249,6 +256,9 @@ main (int argc, char **argv)
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = RIPNG_VTY_PORT; vty_port = RIPNG_VTY_PORT;
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, RIPNG_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
@ -303,7 +313,7 @@ main (int argc, char **argv)
} }
/* Create VTY socket */ /* 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. */ /* Process id file create. */
pid_output (pid_file); pid_output (pid_file);

View File

@ -2898,13 +2898,34 @@ vtysh_connect (struct vtysh_client *vclient)
int sock, len; int sock, len;
struct sockaddr_un addr; struct sockaddr_un addr;
struct stat s_stat; 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. */ /* 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) if (ret < 0 && errno != ENOENT)
{ {
fprintf (stderr, "vtysh_connect(%s): stat = %s\n", fprintf (stderr, "vtysh_connect(%s): stat = %s\n",
vclient->path, safe_strerror(errno)); path, safe_strerror(errno));
exit(1); exit(1);
} }
@ -2913,7 +2934,7 @@ vtysh_connect (struct vtysh_client *vclient)
if (! S_ISSOCK(s_stat.st_mode)) if (! S_ISSOCK(s_stat.st_mode))
{ {
fprintf (stderr, "vtysh_connect(%s): Not a socket\n", fprintf (stderr, "vtysh_connect(%s): Not a socket\n",
vclient->path); path);
exit (1); exit (1);
} }
@ -2923,7 +2944,7 @@ vtysh_connect (struct vtysh_client *vclient)
if (sock < 0) if (sock < 0)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "vtysh_connect(%s): socket = %s\n", vclient->path, fprintf(stderr, "vtysh_connect(%s): socket = %s\n", path,
safe_strerror(errno)); safe_strerror(errno));
#endif /* DEBUG */ #endif /* DEBUG */
return -1; return -1;
@ -2931,7 +2952,7 @@ vtysh_connect (struct vtysh_client *vclient)
memset (&addr, 0, sizeof (struct sockaddr_un)); memset (&addr, 0, sizeof (struct sockaddr_un));
addr.sun_family = AF_UNIX; 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 #ifdef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN
len = addr.sun_len = SUN_LEN(&addr); len = addr.sun_len = SUN_LEN(&addr);
#else #else
@ -2942,7 +2963,7 @@ vtysh_connect (struct vtysh_client *vclient)
if (ret < 0) if (ret < 0)
{ {
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "vtysh_connect(%s): connect = %s\n", vclient->path, fprintf(stderr, "vtysh_connect(%s): connect = %s\n", path,
safe_strerror(errno)); safe_strerror(errno));
#endif /* DEBUG */ #endif /* DEBUG */
close (sock); close (sock);
@ -2993,14 +3014,23 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
{ {
struct vtysh_client *client; struct vtysh_client *client;
char *ptr; char *ptr;
char vty_dir[MAXPATHLEN];
DIR *dir; DIR *dir;
struct dirent *file; struct dirent *file;
int n = 0; int n = 0;
if (head_client->flag != VTYSH_OSPFD) return; if (head_client->flag != VTYSH_OSPFD) return;
/* ls DAEMON_VTY_DIR and look for all files ending in .vty */ if (vty_sock_path == NULL)
dir = opendir(DAEMON_VTY_DIR "/"); /* 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) if (dir)
{ {
while ((file = readdir(dir)) != NULL) while ((file = readdir(dir)) != NULL)
@ -3010,8 +3040,8 @@ vtysh_update_all_insances(struct vtysh_client * head_client)
if (n == MAXIMUM_INSTANCES) if (n == MAXIMUM_INSTANCES)
{ {
fprintf(stderr, fprintf(stderr,
"Parsing %s/, client limit(%d) reached!\n", "Parsing %s, client limit(%d) reached!\n",
DAEMON_VTY_DIR, n); vty_dir, n);
break; break;
} }
client = (struct vtysh_client *) malloc(sizeof(struct vtysh_client)); 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->name = "ospfd";
client->flag = VTYSH_OSPFD; client->flag = VTYSH_OSPFD;
ptr = (char *) malloc(100); 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->path = (const char *)ptr;
client->next = NULL; client->next = NULL;
vtysh_client_sorted_insert(head_client, client); vtysh_client_sorted_insert(head_client, client);

View File

@ -96,4 +96,6 @@ extern int execute_flag;
extern struct vty *vty; extern struct vty *vty;
extern char * vty_sock_path;
#endif /* VTYSH_H */ #endif /* VTYSH_H */

View File

@ -45,14 +45,17 @@
char *progname; char *progname;
/* Configuration file name and directory. */ /* Configuration file name and directory. */
static char vtysh_config_always[] = SYSCONFDIR VTYSH_DEFAULT_CONFIG; static char vtysh_config_always[MAXPATHLEN] = SYSCONFDIR VTYSH_DEFAULT_CONFIG;
static char quagga_config_default[] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG; static char quagga_config_default[MAXPATHLEN] = SYSCONFDIR QUAGGA_DEFAULT_CONFIG;
char *quagga_config = quagga_config_default; char *quagga_config = quagga_config_default;
char history_file[MAXPATHLEN]; char history_file[MAXPATHLEN];
/* Flag for indicate executing child command. */ /* Flag for indicate executing child command. */
int execute_flag = 0; int execute_flag = 0;
/* VTY Socket prefix */
char * vty_sock_path = NULL;
/* For sigsetjmp() & siglongjmp(). */ /* For sigsetjmp() & siglongjmp(). */
static sigjmp_buf jmpbuf; static sigjmp_buf jmpbuf;
@ -144,8 +147,11 @@ usage (int status)
"-f, --inputfile Execute commands from specific file and exit\n" \ "-f, --inputfile Execute commands from specific file and exit\n" \
"-E, --echo Echo prompt and command in -c mode\n" \ "-E, --echo Echo prompt and command in -c mode\n" \
"-C, --dryrun Check configuration for validity and exit\n" \ "-C, --dryrun Check configuration for validity and exit\n" \
"-m, --markfile Mark input file with context end\n" " --vty_socket Override vty socket path\n" \
"-w, --writeconfig Write integrated config (Quagga.conf) and exit\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" \ "-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" \
"line by passing multiple -c args, or by embedding linefeed\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. */ /* VTY shell options, we use GNU getopt library. */
#define OPTION_VTYSOCK 1000
#define OPTION_CONFDIR 1001
struct option longopts[] = struct option longopts[] =
{ {
{ "boot", no_argument, NULL, 'b'}, { "boot", no_argument, NULL, 'b'},
@ -163,6 +171,8 @@ struct option longopts[] =
{ "eval", required_argument, NULL, 'e'}, { "eval", required_argument, NULL, 'e'},
{ "command", required_argument, NULL, 'c'}, { "command", required_argument, NULL, 'c'},
{ "daemon", required_argument, NULL, 'd'}, { "daemon", required_argument, NULL, 'd'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK},
{ "config_dir", required_argument, NULL, OPTION_CONFDIR},
{ "inputfile", required_argument, NULL, 'f'}, { "inputfile", required_argument, NULL, 'f'},
{ "echo", no_argument, NULL, 'E'}, { "echo", no_argument, NULL, 'E'},
{ "dryrun", no_argument, NULL, 'C'}, { "dryrun", no_argument, NULL, 'C'},
@ -262,6 +272,7 @@ main (int argc, char **argv, char **env)
int boot_flag = 0; int boot_flag = 0;
const char *daemon_name = NULL; const char *daemon_name = NULL;
const char *inputfile = NULL; const char *inputfile = NULL;
char *vtysh_configfile_name;
struct cmd_rec { struct cmd_rec {
const char *line; const char *line;
struct cmd_rec *next; struct cmd_rec *next;
@ -274,6 +285,9 @@ main (int argc, char **argv, char **env)
int ret = 0; int ret = 0;
char *homedir = NULL; char *homedir = NULL;
/* check for restricted functionality if vtysh is run setuid */
int restricted = (getuid() != geteuid()) || (getgid() != getegid());
/* Preserve name of myself. */ /* Preserve name of myself. */
progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]);
@ -310,6 +324,55 @@ main (int argc, char **argv, char **env)
tail = cr; tail = cr;
} }
break; 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': case 'd':
daemon_name = optarg; daemon_name = optarg;
break; break;

View File

@ -218,7 +218,12 @@ char *
vtysh_get_home (void) vtysh_get_home (void)
{ {
struct passwd *passwd; struct passwd *passwd;
char * homedir;
if ((homedir = getenv("HOME")) != 0)
return homedir;
/* Fallback if HOME is undefined */
passwd = getpwuid (getuid ()); passwd = getpwuid (getuid ());
return passwd ? passwd->pw_dir : NULL; return passwd ? passwd->pw_dir : NULL;

View File

@ -59,6 +59,9 @@ struct zebra_t zebrad =
/* process id. */ /* process id. */
pid_t pid; pid_t pid;
/* VTY Socket prefix */
char vty_sock_path[MAXPATHLEN] = ZEBRA_VTYSH_PATH;
/* Pacify zclient.o in libzebra, which expects this variable. */ /* Pacify zclient.o in libzebra, which expects this variable. */
struct thread_master *master; struct thread_master *master;
@ -77,6 +80,7 @@ u_int32_t nl_rcvbufsize = 4194304;
#endif /* HAVE_NETLINK */ #endif /* HAVE_NETLINK */
/* Command line options. */ /* Command line options. */
#define OPTION_VTYSOCK 1000
struct option longopts[] = struct option longopts[] =
{ {
{ "batch", no_argument, NULL, 'b'}, { "batch", no_argument, NULL, 'b'},
@ -90,6 +94,7 @@ struct option longopts[] =
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "vty_socket", required_argument, NULL, OPTION_VTYSOCK },
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "dryrun", no_argument, NULL, 'C'}, { "dryrun", no_argument, NULL, 'C'},
#ifdef HAVE_NETLINK #ifdef HAVE_NETLINK
@ -152,6 +157,7 @@ usage (char *progname, int status)
"-C, --dryrun Check configuration for validity and exit\n"\ "-C, --dryrun Check configuration for validity and exit\n"\
"-A, --vty_addr Set vty's bind address\n"\ "-A, --vty_addr Set vty's bind address\n"\
"-P, --vty_port Set vty's port number\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 "\ "-r, --retain When program terminates, retain added route "\
"by zebra.\n"\ "by zebra.\n"\
"-u, --user User to run as\n"\ "-u, --user User to run as\n"\
@ -259,6 +265,7 @@ main (int argc, char **argv)
char *p; char *p;
char *vty_addr = NULL; char *vty_addr = NULL;
int vty_port = ZEBRA_VTY_PORT; int vty_port = ZEBRA_VTY_PORT;
char *vty_sock_name;
int dryrun = 0; int dryrun = 0;
int batch_mode = 0; int batch_mode = 0;
int daemon_mode = 0; int daemon_mode = 0;
@ -339,6 +346,9 @@ main (int argc, char **argv)
if (vty_port <= 0 || vty_port > 0xffff) if (vty_port <= 0 || vty_port > 0xffff)
vty_port = ZEBRA_VTY_PORT; vty_port = ZEBRA_VTY_PORT;
break; break;
case OPTION_VTYSOCK:
set_socket_path(vty_sock_path, ZEBRA_VTYSH_PATH, optarg, sizeof (vty_sock_path));
break;
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
@ -463,7 +473,7 @@ main (int argc, char **argv)
zebra_zserv_socket_init (zserv_path); zebra_zserv_socket_init (zserv_path);
/* Make vty server socket. */ /* 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. */ /* Print banner. */
zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, vty_port); zlog_notice ("Zebra %s starting: vty@%d", FRR_VERSION, vty_port);