#define _ZEBRA_PRIVS_H
#include <pthread.h>
+#include "lib/queue.h"
#ifdef __cplusplus
extern "C" {
ZPRIVS_LOWER,
} zebra_privs_ops_t;
+struct zebra_privs_refs_t {
+ STAILQ_ENTRY(zebra_privs_refs_t) entry;
+ pthread_t tid;
+ uint32_t refcount;
+ const char *raised_in_funcname;
+};
+
struct zebra_privs_t {
zebra_capabilities_t *caps_p; /* caps required for operation */
zebra_capabilities_t *caps_i; /* caps to allow inheritance of */
int cap_num_i;
/* Mutex and counter used to avoid race conditions in multi-threaded
- * processes. The privs elevation is process-wide, so we need to
- * avoid changing the privilege status across threads.
+ * processes. If privs status is process-wide, we need to
+ * control changes to the privilege status among threads.
+ * If privs changes are per-thread, we need to be able to
+ * manage that too.
*/
pthread_mutex_t mutex;
- uint32_t refcount;
+ struct zebra_privs_refs_t process_refs;
+
+ STAILQ_HEAD(thread_refs_q, zebra_privs_refs_t) thread_refs;
const char *user; /* user and group to run as */
const char *group;
int (*change)(zebra_privs_ops_t); /* change privileges, 0 on success */
zebra_privs_current_t (*current_state)(
void); /* current privilege state */
- const char *raised_in_funcname;
};
struct zprivs_ids_t {
/*
* Wrapper around zprivs, to be used as:
- * frr_elevate_privs(&privs) {
+ * frr_with_privs(&privs) {
* ... code ...
* if (error)
* break; -- break can be used to get out of the block
* ... code ...
* }
*
- * The argument to frr_elevate_privs() can be NULL to leave privileges as-is
+ * The argument to frr_with_privs() can be NULL to leave privileges as-is
* (mostly useful for conditional privilege-raising, i.e.:)
- * frr_elevate_privs(cond ? &privs : NULL) {}
+ * frr_with_privs(cond ? &privs : NULL) {}
*
* NB: The code block is always executed, regardless of whether privileges
* could be raised or not, or whether NULL was given or not. This is fully
const char *funcname);
extern void _zprivs_lower(struct zebra_privs_t **privs);
-#define frr_elevate_privs(privs) \
+#define frr_with_privs(privs) \
for (struct zebra_privs_t *_once = NULL, \
*_privs __attribute__( \
(unused, cleanup(_zprivs_lower))) = \