diff options
| author | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-02-02 10:42:51 -0500 |
|---|---|---|
| committer | Donald Sharp <sharpd@cumulusnetworks.com> | 2017-02-02 10:42:51 -0500 |
| commit | 1a35e2e56533f75d68ed30bf24b3c131da4ba950 (patch) | |
| tree | 068c7730ed7a58d5374d8123d81720597b40bbcd /lib | |
| parent | b384af46d50caaae87e1c7807227ac6b4d87f377 (diff) | |
| parent | 56041a77064fe6924ca55dd4e394777b7a5900d0 (diff) | |
Merge remote-tracking branch 'origin/stable/2.0'
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/plist.c | 4 | ||||
| -rw-r--r-- | lib/privs.c | 21 | ||||
| -rw-r--r-- | lib/sockopt.c | 23 | ||||
| -rw-r--r-- | lib/sockopt.h | 4 | ||||
| -rw-r--r-- | lib/vty.c | 5 |
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); @@ -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) ) |
