]> git.proxmox.com Git - mirror_frr.git/blobdiff - lib/privs.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / lib / privs.c
index eda3fb02d4c0b72a7ea33b6504210107e256b9ea..838ff8fc928fae844c6cfad3a9401baf0a45c403 100644 (file)
@@ -24,6 +24,7 @@
 #include "log.h"
 #include "privs.h"
 #include "memory.h"
+#include "lib_errors.h"
 
 #ifdef HAVE_CAPABILITIES
 
@@ -288,7 +289,8 @@ zebra_privs_current_t zprivs_state_caps(void)
                if (cap_get_flag(zprivs_state.caps,
                                 zprivs_state.syscaps_p->caps[i], CAP_EFFECTIVE,
                                 &val)) {
-                       zlog_warn(
+                       flog_err(
+                               EC_LIB_SYSTEM_CALL,
                                "zprivs_state_caps: could not cap_get_flag, %s",
                                safe_strerror(errno));
                        return ZPRIVS_UNKNOWN;
@@ -696,6 +698,41 @@ static int getgrouplist(const char *user, gid_t group, gid_t *groups,
 }
 #endif /* HAVE_GETGROUPLIST */
 
+struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs,
+                                   const char *funcname)
+{
+       int save_errno = errno;
+
+       if (!privs)
+               return NULL;
+
+       errno = 0;
+       if (privs->change(ZPRIVS_RAISE)) {
+               zlog_err("%s: Failed to raise privileges (%s)",
+                        funcname, safe_strerror(errno));
+       }
+       errno = save_errno;
+       privs->raised_in_funcname = funcname;
+       return privs;
+}
+
+void _zprivs_lower(struct zebra_privs_t **privs)
+{
+       int save_errno = errno;
+
+       if (!*privs)
+               return;
+
+       errno = 0;
+       if ((*privs)->change(ZPRIVS_LOWER)) {
+               zlog_err("%s: Failed to lower privileges (%s)",
+                        (*privs)->raised_in_funcname, safe_strerror(errno));
+       }
+       errno = save_errno;
+       (*privs)->raised_in_funcname = NULL;
+       *privs = NULL;
+}
+
 void zprivs_preinit(struct zebra_privs_t *zprivs)
 {
        struct passwd *pwentry = NULL;
@@ -824,6 +861,19 @@ void zprivs_init(struct zebra_privs_t *zprivs)
 
 #ifdef HAVE_CAPABILITIES
        zprivs_caps_init(zprivs);
+
+       /*
+        * If we have initialized the system with no requested
+        * capabilities, change will not have been set
+        * to anything by zprivs_caps_init, As such
+        * we should make sure that when we attempt
+        * to raize privileges that we actually have
+        * a do nothing function to call instead of a
+        * crash :).
+        */
+       if (!zprivs->change)
+               zprivs->change = zprivs_change_null;
+
 #else  /* !HAVE_CAPABILITIES */
        /* we dont have caps. we'll need to maintain rid and saved uid
         * and change euid back to saved uid (who we presume has all neccessary
@@ -856,7 +906,9 @@ void zprivs_terminate(struct zebra_privs_t *zprivs)
        }
 
 #ifdef HAVE_CAPABILITIES
-       zprivs_caps_terminate();
+       if (zprivs->user || zprivs->group || zprivs->cap_num_p
+           || zprivs->cap_num_i)
+               zprivs_caps_terminate();
 #else  /* !HAVE_CAPABILITIES */
        /* only change uid if we don't have the correct one */
        if ((zprivs_state.zuid) && (zprivs_state.zsuid != zprivs_state.zuid)) {