summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDonald Sharp <sharpd@cumulusnetworks.com>2017-02-02 10:42:51 -0500
committerDonald Sharp <sharpd@cumulusnetworks.com>2017-02-02 10:42:51 -0500
commit1a35e2e56533f75d68ed30bf24b3c131da4ba950 (patch)
tree068c7730ed7a58d5374d8123d81720597b40bbcd /lib
parentb384af46d50caaae87e1c7807227ac6b4d87f377 (diff)
parent56041a77064fe6924ca55dd4e394777b7a5900d0 (diff)
Merge remote-tracking branch 'origin/stable/2.0'
Diffstat (limited to 'lib')
-rw-r--r--lib/plist.c4
-rw-r--r--lib/privs.c21
-rw-r--r--lib/sockopt.c23
-rw-r--r--lib/sockopt.h4
-rw-r--r--lib/vty.c5
5 files changed, 49 insertions, 8 deletions
diff --git a/lib/plist.c b/lib/plist.c
index 279c85d6d6..41cae020de 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -326,6 +326,9 @@ prefix_list_get (afi_t afi, int orf, const char *name)
return plist;
}
+static void prefix_list_trie_del (struct prefix_list *plist,
+ struct prefix_list_entry *pentry);
+
/* Delete prefix-list from prefix_list_master and free it. */
static void
prefix_list_delete (struct prefix_list *plist)
@@ -339,6 +342,7 @@ prefix_list_delete (struct prefix_list *plist)
for (pentry = plist->head; pentry; pentry = next)
{
next = pentry->next;
+ prefix_list_trie_del (plist, pentry);
prefix_list_entry_free (pentry);
plist->count--;
}
diff --git a/lib/privs.c b/lib/privs.c
index ac2a8454c5..376d6f3365 100644
--- a/lib/privs.c
+++ b/lib/privs.c
@@ -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) )
{
diff --git a/lib/sockopt.c b/lib/sockopt.c
index 2a9f907cb3..91b0602b3a 100644
--- a/lib/sockopt.c
+++ b/lib/sockopt.c
@@ -29,6 +29,29 @@
#include "sockopt.h"
#include "sockunion.h"
+/* Replace the path of given defaultpath with newpath, but keep filename */
+void
+set_socket_path (char *path, const char *defaultpath, char *newpath, int maxsize)
+{
+ const 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)
{
diff --git a/lib/sockopt.h b/lib/sockopt.h
index 1b7be1e49f..d5724ce60f 100644
--- a/lib/sockopt.h
+++ b/lib/sockopt.h
@@ -24,6 +24,10 @@
#include "sockunion.h"
+/* Override (vty) socket paths, but keep the filename */
+extern void set_socket_path (char *path, const 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);
diff --git a/lib/vty.c b/lib/vty.c
index 9e0625e3cb..b6f493b6c9 100644
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -2022,7 +2022,10 @@ vty_serv_un (const char *path)
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) )