]>
Commit | Line | Data |
---|---|---|
d62a17ae | 1 | /* |
01245821 | 2 | * Zebra privileges header. |
3 | * | |
4 | * Copyright (C) 2003 Paul Jakma. | |
5 | * | |
6 | * This file is part of GNU Zebra. | |
7 | * | |
8 | * GNU Zebra is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2, or (at your option) any | |
11 | * later version. | |
12 | * | |
13 | * GNU Zebra is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
896014f4 DL |
18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; see the file COPYING; if not, write to the Free Software | |
20 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | |
01245821 | 21 | */ |
22 | ||
23 | #ifndef _ZEBRA_PRIVS_H | |
24 | #define _ZEBRA_PRIVS_H | |
25 | ||
c5c44d4b | 26 | #include <pthread.h> |
31f937fb | 27 | #include <stdint.h> |
8875d051 | 28 | #include "lib/queue.h" |
c5c44d4b | 29 | |
5e244469 RW |
30 | #ifdef __cplusplus |
31 | extern "C" { | |
32 | #endif | |
33 | ||
01245821 | 34 | /* list of zebra capabilities */ |
d62a17ae | 35 | typedef enum { |
36 | ZCAP_SETID, | |
37 | ZCAP_BIND, | |
38 | ZCAP_NET_ADMIN, | |
39 | ZCAP_SYS_ADMIN, | |
40 | ZCAP_NET_RAW, | |
41 | ZCAP_CHROOT, | |
42 | ZCAP_NICE, | |
43 | ZCAP_PTRACE, | |
44 | ZCAP_DAC_OVERRIDE, | |
45 | ZCAP_READ_SEARCH, | |
46 | ZCAP_FOWNER, | |
575a2597 | 47 | ZCAP_IPC_LOCK, |
d62a17ae | 48 | ZCAP_MAX |
01245821 | 49 | } zebra_capabilities_t; |
50 | ||
d62a17ae | 51 | typedef enum { |
52 | ZPRIVS_LOWERED, | |
53 | ZPRIVS_RAISED, | |
54 | ZPRIVS_UNKNOWN, | |
01245821 | 55 | } zebra_privs_current_t; |
56 | ||
d62a17ae | 57 | typedef enum { |
58 | ZPRIVS_RAISE, | |
59 | ZPRIVS_LOWER, | |
01245821 | 60 | } zebra_privs_ops_t; |
61 | ||
8875d051 MS |
62 | struct zebra_privs_refs_t { |
63 | STAILQ_ENTRY(zebra_privs_refs_t) entry; | |
64 | pthread_t tid; | |
65 | uint32_t refcount; | |
66 | const char *raised_in_funcname; | |
67 | }; | |
68 | ||
d62a17ae | 69 | struct zebra_privs_t { |
70 | zebra_capabilities_t *caps_p; /* caps required for operation */ | |
71 | zebra_capabilities_t *caps_i; /* caps to allow inheritance of */ | |
72 | int cap_num_p; /* number of caps in arrays */ | |
73 | int cap_num_i; | |
c5c44d4b MS |
74 | |
75 | /* Mutex and counter used to avoid race conditions in multi-threaded | |
8875d051 MS |
76 | * processes. If privs status is process-wide, we need to |
77 | * control changes to the privilege status among threads. | |
78 | * If privs changes are per-thread, we need to be able to | |
79 | * manage that too. | |
c5c44d4b MS |
80 | */ |
81 | pthread_mutex_t mutex; | |
8875d051 MS |
82 | struct zebra_privs_refs_t process_refs; |
83 | ||
84 | STAILQ_HEAD(thread_refs_q, zebra_privs_refs_t) thread_refs; | |
c5c44d4b | 85 | |
d62a17ae | 86 | const char *user; /* user and group to run as */ |
87 | const char *group; | |
88 | const char *vty_group; /* group to chown vty socket to */ | |
89 | /* methods */ | |
90 | int (*change)(zebra_privs_ops_t); /* change privileges, 0 on success */ | |
91 | zebra_privs_current_t (*current_state)( | |
92 | void); /* current privilege state */ | |
01245821 | 93 | }; |
94 | ||
d62a17ae | 95 | struct zprivs_ids_t { |
96 | /* -1 is undefined */ | |
97 | uid_t uid_priv; /* privileged uid */ | |
98 | uid_t uid_normal; /* normal uid */ | |
99 | gid_t gid_priv; /* privileged uid */ | |
100 | gid_t gid_normal; /* normal uid */ | |
101 | gid_t gid_vty; /* vty gid */ | |
ba3a0bc5 | 102 | }; |
103 | ||
877057b6 DL |
104 | extern struct zebra_privs_t *lib_privs; |
105 | ||
d62a17ae | 106 | /* initialise zebra privileges */ |
37a1f2fb | 107 | extern void zprivs_preinit(struct zebra_privs_t *zprivs); |
d62a17ae | 108 | extern void zprivs_init(struct zebra_privs_t *zprivs); |
109 | /* drop all and terminate privileges */ | |
110 | extern void zprivs_terminate(struct zebra_privs_t *); | |
111 | /* query for runtime uid's and gid's, eg vty needs this */ | |
8cc4198f | 112 | extern void zprivs_get_ids(struct zprivs_ids_t *); |
01245821 | 113 | |
6017c3a2 DL |
114 | /* |
115 | * Wrapper around zprivs, to be used as: | |
0cf6db21 | 116 | * frr_with_privs(&privs) { |
6017c3a2 DL |
117 | * ... code ... |
118 | * if (error) | |
119 | * break; -- break can be used to get out of the block | |
120 | * ... code ... | |
121 | * } | |
122 | * | |
0cf6db21 | 123 | * The argument to frr_with_privs() can be NULL to leave privileges as-is |
6017c3a2 | 124 | * (mostly useful for conditional privilege-raising, i.e.:) |
0cf6db21 | 125 | * frr_with_privs(cond ? &privs : NULL) {} |
6017c3a2 DL |
126 | * |
127 | * NB: The code block is always executed, regardless of whether privileges | |
128 | * could be raised or not, or whether NULL was given or not. This is fully | |
129 | * intentional; the user may have configured some RBAC or similar that we | |
130 | * are not aware of, but that allows our code to proceed without privileges. | |
131 | * | |
132 | * The point of this wrapper is to prevent accidental bugs where privileges | |
133 | * are elevated but then not dropped. This can happen when, for example, a | |
134 | * "return", "goto" or "break" in the middle of the elevated-privilege code | |
135 | * skips past the privilege dropping call. | |
136 | * | |
137 | * The macro below uses variable cleanup to drop privileges as soon as the | |
138 | * code block is left in any way (and thus the _privs variable goes out of | |
139 | * scope.) _once is just a trick to run the loop exactly once. | |
140 | */ | |
141 | extern struct zebra_privs_t *_zprivs_raise(struct zebra_privs_t *privs, | |
142 | const char *funcname); | |
143 | extern void _zprivs_lower(struct zebra_privs_t **privs); | |
144 | ||
0cf6db21 | 145 | #define frr_with_privs(privs) \ |
6017c3a2 DL |
146 | for (struct zebra_privs_t *_once = NULL, \ |
147 | *_privs __attribute__( \ | |
148 | (unused, cleanup(_zprivs_lower))) = \ | |
149 | _zprivs_raise(privs, __func__); \ | |
150 | _once == NULL; _once = (void *)1) | |
151 | ||
5e244469 RW |
152 | #ifdef __cplusplus |
153 | } | |
154 | #endif | |
155 | ||
01245821 | 156 | #endif /* _ZEBRA_PRIVS_H */ |