diff options
Diffstat (limited to 'lib/privs.c')
| -rw-r--r-- | lib/privs.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/lib/privs.c b/lib/privs.c index 2932800070..3ce8e0d57a 100644 --- a/lib/privs.c +++ b/lib/privs.c @@ -706,6 +706,14 @@ struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs, if (!privs) return NULL; + /* If we're already elevated, just return */ + pthread_mutex_lock(&(privs->mutex)); + if (++privs->refcount > 1) { + pthread_mutex_unlock(&(privs->mutex)); + return privs; + } + pthread_mutex_unlock(&(privs->mutex)); + errno = 0; if (privs->change(ZPRIVS_RAISE)) { zlog_err("%s: Failed to raise privileges (%s)", @@ -723,6 +731,14 @@ void _zprivs_lower(struct zebra_privs_t **privs) if (!*privs) return; + /* Don't lower privs if there's another caller */ + pthread_mutex_lock(&(*privs)->mutex); + if (--((*privs)->refcount) > 0) { + pthread_mutex_unlock(&(*privs)->mutex); + return; + } + pthread_mutex_unlock(&(*privs)->mutex); + errno = 0; if ((*privs)->change(ZPRIVS_LOWER)) { zlog_err("%s: Failed to lower privileges (%s)", @@ -743,6 +759,9 @@ void zprivs_preinit(struct zebra_privs_t *zprivs) exit(1); } + pthread_mutex_init(&(zprivs->mutex), NULL); + zprivs->refcount = 0; + if (zprivs->vty_group) { /* in a "NULL" setup, this is allowed to fail too, but still * try. */ |
