From: David Lamparter Date: Thu, 1 Jun 2017 16:33:08 +0000 (+0200) Subject: lib: privs: make uid/gid accessible before setuid X-Git-Tag: frr-4.0-dev~435^2~9 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=37a1f2fbb6e05053098a5f1af5eff16ac523dd35;p=mirror%2Ffrr.git lib: privs: make uid/gid accessible before setuid This splits off privs_preinit(), which does the lookups for user and group IDs. This is so the init code can create state directories while still running as root. Signed-off-by: David Lamparter --- diff --git a/ldpd/lde.c b/ldpd/lde.c index 77643ff48b..6c74c20125 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -164,6 +164,7 @@ lde_init(struct ldpd_init *init) /* drop privileges */ lde_privs.user = init->user; lde_privs.group = init->group; + zprivs_preinit(&lde_privs); zprivs_init(&lde_privs); /* start the LIB garbage collector */ diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index b2f9fdce55..1c0a8bdc84 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -142,6 +142,7 @@ ldpe_init(struct ldpd_init *init) /* drop privileges */ ldpe_privs.user = init->user; ldpe_privs.group = init->group; + zprivs_preinit(&ldpe_privs); zprivs_init(&ldpe_privs); /* listen on ldpd control socket */ diff --git a/lib/libfrr.c b/lib/libfrr.c index d168d83053..e0bba297e0 100644 --- a/lib/libfrr.c +++ b/lib/libfrr.c @@ -347,6 +347,8 @@ struct thread_master *frr_init(void) snprintf(frr_protonameinst, sizeof(frr_protonameinst), "%s[%u]", di->logname, di->instance); + zprivs_preinit(di->privs); + openzlog(di->progname, di->logname, di->instance, LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON); #if defined(HAVE_CUMULUS) diff --git a/lib/privs.c b/lib/privs.c index c971596117..eda3fb02d4 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -696,13 +696,10 @@ static int getgrouplist(const char *user, gid_t group, gid_t *groups, } #endif /* HAVE_GETGROUPLIST */ -void zprivs_init(struct zebra_privs_t *zprivs) +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"); @@ -751,6 +748,18 @@ void zprivs_init(struct zebra_privs_t *zprivs) 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); diff --git a/lib/privs.h b/lib/privs.h index c18fe78add..7fe59328b2 100644 --- a/lib/privs.h +++ b/lib/privs.h @@ -74,6 +74,7 @@ struct zprivs_ids_t { }; /* initialise zebra privileges */ +extern void zprivs_preinit(struct zebra_privs_t *zprivs); extern void zprivs_init(struct zebra_privs_t *zprivs); /* drop all and terminate privileges */ extern void zprivs_terminate(struct zebra_privs_t *); diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c index 5713105f42..03b543a786 100644 --- a/ospfclient/ospfclient.c +++ b/ospfclient/ospfclient.c @@ -307,6 +307,7 @@ int main(int argc, char *argv[]) } /* Initialization */ + zprivs_preinit(&ospfd_privs); zprivs_init(&ospfd_privs); master = thread_master_create(NULL); diff --git a/tests/lib/test_privs.c b/tests/lib/test_privs.c index c2cb5c2ea5..1984f28e63 100644 --- a/tests/lib/test_privs.c +++ b/tests/lib/test_privs.c @@ -108,6 +108,7 @@ int main(int argc, char **argv) /* Library inits. */ memory_init(); + zprivs_preinit(&test_privs); zprivs_init(&test_privs); #define PRIV_STATE() \