* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
- * You should have received a copy of the GNU General Public License
- * along with GNU Zebra; see the file COPYING. If not, write to the Free
- * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- * 02111-1307, USA.
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "log.h"
#include "privs.h"
#include "memory.h"
+#include "lib_errors.h"
#ifdef HAVE_CAPABILITIES
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;
}
#endif /* HAVE_GETGROUPLIST */
-void zprivs_init(struct zebra_privs_t *zprivs)
+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;
struct group *grentry = NULL;
- gid_t groups[NGROUPS_MAX];
- int i, ngroups = 0;
- int found = 0;
if (!zprivs) {
fprintf(stderr, "zprivs_init: called with NULL arg!\n");
zprivs_state.zgid = grentry->gr_gid;
}
+}
+
+void zprivs_init(struct zebra_privs_t *zprivs)
+{
+ gid_t groups[NGROUPS_MAX];
+ int i, ngroups = 0;
+ int found = 0;
+
+ /* NULL privs */
+ if (!(zprivs->user || zprivs->group || zprivs->cap_num_p
+ || zprivs->cap_num_i))
+ return;
if (zprivs->user) {
ngroups = sizeof(groups);
}
}
+ zprivs_state.zsuid = geteuid(); /* initial uid */
/* add groups only if we changed uid - otherwise skip */
if ((ngroups) && (zprivs_state.zsuid != zprivs_state.zuid)) {
if (setgroups(ngroups, groups)) {
#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
}
#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)) {