diff options
Diffstat (limited to 'lib/privs.c')
-rw-r--r-- | lib/privs.c | 106 |
1 files changed, 38 insertions, 68 deletions
diff --git a/lib/privs.c b/lib/privs.c index 9139823e..35e5a76b 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -40,7 +40,6 @@ static struct _zprivs_t uid_t zuid, /* uid to run as */ zsuid; /* saved uid */ gid_t zgid; /* gid to run as */ - gid_t vtygrp; /* gid for vty sockets */ } zprivs_state; /* externally exported but not directly accessed functions */ @@ -70,9 +69,11 @@ cap_map [ZCAP_MAX] = [ZCAP_DAC_OVERRIDE] = CAP_DAC_OVERRIDE, [ZCAP_READ_SEARCH] = CAP_DAC_READ_SEARCH, [ZCAP_SYS_ADMIN] = CAP_SYS_ADMIN, - [ZCAP_FOWNER] = CAP_FOWNER + [ZCAP_FOWNER] = ZCAP_FOWNER }; +static cap_value_t cap_setuid_value [] = { CAP_SETUID }; + /* convert zebras privileges to system capabilities */ static cap_value_t * zcaps2sys (zebra_capabilities_t *zcaps, int num) @@ -175,12 +176,6 @@ zprivs_init(struct zebra_privs_t *zprivs) struct passwd *pwentry = NULL; struct group *grentry = NULL; - if (!zprivs) - { - zlog_err ("zprivs_init: called with NULL arg!"); - exit (1); - } - /* NULL privs */ if (! (zprivs->user || zprivs->group || zprivs->cap_num_p || zprivs->cap_num_i) ) @@ -193,31 +188,7 @@ zprivs_init(struct zebra_privs_t *zprivs) if (zprivs->user) { if ( (pwentry = getpwnam (zprivs->user)) ) - { - zprivs_state.zuid = pwentry->pw_uid; - } - else - { - zlog_err ("privs_init: could not lookup supplied user"); - exit (1); - } - } - - grentry = NULL; - - if (zprivs->vty_group) - /* Add the vty_group to the supplementary groups so it can be chowned to */ - { - if ( (grentry = getgrnam (zprivs->vty_group)) ) - { - zprivs_state.vtygrp = grentry->gr_gid; - if ( setgroups (1, &zprivs_state.vtygrp) ) - { - zlog_err ("privs_init: could not setgroups, %s", - strerror (errno) ); - exit (1); - } - } + zprivs_state.zuid = pwentry->pw_uid; else { zlog_err ("privs_init: could not lookup supplied user"); @@ -227,20 +198,18 @@ zprivs_init(struct zebra_privs_t *zprivs) if (zprivs->group) { - if ( (grentry = getgrnam (zprivs->group)) ) - { - zprivs_state.zgid = grentry->gr_gid; - } + if ( (grentry = getgrnam (zprivs->user)) ) + zprivs_state.zgid = grentry->gr_gid; else { zlog_err ("privs_init: could not lookup supplied user"); exit (1); } + /* change group now, forever. uid we do later */ if ( setregid (zprivs_state.zgid, zprivs_state.zgid) ) { - zlog_err ("zprivs_init: could not setregid, %s", - strerror (errno) ); + zlog_err ("privs_init: could not setregid"); exit (1); } } @@ -269,17 +238,6 @@ zprivs_init(struct zebra_privs_t *zprivs) zlog_err ("privs_init: failed to cap_init, %s", strerror (errno) ); exit (1); } - - /* we have caps, we have no need to ever change back the original user */ - if (zprivs_state.zuid) - { - if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) ) - { - zlog_err ("zprivs_init (cap): could not setreuid, %s", - strerror (errno) ); - exit (1); - } - } if ( cap_clear (zprivs_state.caps) ) { @@ -293,6 +251,12 @@ zprivs_init(struct zebra_privs_t *zprivs) cap_set_flag(zprivs_state.caps, CAP_EFFECTIVE, zprivs_state.sys_num_p, zprivs_state.syscaps_p, CAP_SET); + /* still need CAP_SETUID for the moment */ + cap_set_flag(zprivs_state.caps, CAP_PERMITTED, + 1, cap_setuid_value, CAP_SET); + cap_set_flag(zprivs_state.caps, CAP_EFFECTIVE, + 1, cap_setuid_value, CAP_SET); + /* set inheritable caps, if any */ if (zprivs_state.sys_num_i) { @@ -300,8 +264,8 @@ zprivs_init(struct zebra_privs_t *zprivs) zprivs_state.sys_num_i, zprivs_state.syscaps_i, CAP_SET); } - /* apply caps. CAP_EFFECTIVE is cleared. we'll raise the caps as - * and when, and only when, they are needed. + /* apply caps. CAP_EFFECTIVE is clear bar cap_setuid_value. + * we'll raise the caps as and when, and only when, they are needed. */ if ( cap_set_proc (zprivs_state.caps) ) { @@ -309,7 +273,28 @@ zprivs_init(struct zebra_privs_t *zprivs) exit (1); } - /* set methods for the caller to use */ + /* we have caps, we have no need to ever change back the original user */ + if (zprivs_state.zuid) + { + if ( setreuid (zprivs_state.zuid, zprivs_state.zuid) ) + { + zlog_err ("privs_init (cap): could not setreuid, %s", strerror (errno) ); + exit (1); + } + } + + /* No more need for cap_setuid_value */ + cap_set_flag(zprivs_state.caps, CAP_PERMITTED, + 1, cap_setuid_value, CAP_CLEAR); + cap_set_flag(zprivs_state.caps, CAP_EFFECTIVE, + 1, cap_setuid_value, CAP_CLEAR); + if ( cap_set_proc (zprivs_state.caps) ) + { + zlog_err ("privs_init: cap_set_proc failed to clear cap_setuid, %s", + strerror (errno) ); + exit (1); + } + zprivs->change = zprivs_change_caps; zprivs->current_state = zprivs_state_caps; @@ -369,18 +354,3 @@ zprivs_terminate (void) #endif /* HAVE_LCAPS */ return; } - -void -zprivs_get_ids(struct zprivs_ids_t *ids) -{ - - ids->uid_priv = getuid(); - (zprivs_state.zuid) ? (ids->uid_normal = zprivs_state.zuid) - : (ids->uid_normal = -1); - (zprivs_state.zgid) ? (ids->gid_normal = zprivs_state.zgid) - : (ids->gid_normal = -1); - (zprivs_state.vtygrp) ? (ids->gid_vty = zprivs_state.vtygrp) - : (ids->gid_vty = -1); - - return; -} |