2 * $Id: privsep-linux.c,v 1.6 2011/02/28 10:53:07 reubenhwk Exp $
5 * Jim Paris <jim@jtan.com>
6 * Pedro Roque <roque@di.fc.ul.pt>
7 * Lars Fenneberg <lf@elemental.net>
9 * This software is Copyright 1996,1997,2008 by the above mentioned author(s),
10 * All Rights Reserved.
12 * The license which is distributed with this software in the file COPYRIGHT
13 * applies to this software. If your distribution is missing this file, you
14 * may request it from <pekkas@netcore.fi>.
21 #include "pathnames.h"
23 int privsep_set(const char *iface
, const char *var
, uint32_t val
);
24 void privsep_read_loop(void);
26 /* For reading or writing, depending on process */
31 SET_INTERFACE_LINKMTU
,
32 SET_INTERFACE_CURHLIM
,
33 SET_INTERFACE_REACHTIME
,
34 SET_INTERFACE_RETRANSTIMER
,
37 /* Command sent over pipe is a fixed size binary structure. */
38 struct privsep_command
{
44 /* Privileged read loop */
46 privsep_read_loop(void)
48 struct privsep_command cmd
;
52 ret
= readn(pfd
, &cmd
, sizeof(cmd
));
54 /* Error or EOF, give up */
56 flog(LOG_ERR
, "Exiting, privsep_read_loop had readn error: %s\n",
59 flog(LOG_ERR
, "Exiting, privsep_read_loop had readn return 0 bytes\n");
64 if (ret
!= sizeof(cmd
)) {
65 /* Short read, ignore */
69 cmd
.iface
[IFNAMSIZ
-1] = '\0';
73 case SET_INTERFACE_LINKMTU
:
74 if (cmd
.val
< MIN_AdvLinkMTU
|| cmd
.val
> MAX_AdvLinkMTU
) {
75 flog(LOG_ERR
, "(privsep) %s: LinkMTU (%u) is not within the defined bounds, ignoring", cmd
.iface
, cmd
.val
);
78 ret
= set_interface_var(cmd
.iface
, PROC_SYS_IP6_LINKMTU
, "LinkMTU", cmd
.val
);
81 case SET_INTERFACE_CURHLIM
:
82 if (cmd
.val
< MIN_AdvCurHopLimit
|| cmd
.val
> MAX_AdvCurHopLimit
) {
83 flog(LOG_ERR
, "(privsep) %s: CurHopLimit (%u) is not within the defined bounds, ignoring", cmd
.iface
, cmd
.val
);
86 ret
= set_interface_var(cmd
.iface
, PROC_SYS_IP6_CURHLIM
, "CurHopLimit", cmd
.val
);
89 case SET_INTERFACE_REACHTIME
:
90 if (cmd
.val
< MIN_AdvReachableTime
|| cmd
.val
> MAX_AdvReachableTime
) {
91 flog(LOG_ERR
, "(privsep) %s: BaseReachableTimer (%u) is not within the defined bounds, ignoring", cmd
.iface
, cmd
.val
);
94 ret
= set_interface_var(cmd
.iface
, PROC_SYS_IP6_BASEREACHTIME_MS
, "BaseReachableTimer (ms)", cmd
.val
);
97 set_interface_var(cmd
.iface
, PROC_SYS_IP6_BASEREACHTIME
, "BaseReachableTimer", cmd
.val
/ 1000);
100 case SET_INTERFACE_RETRANSTIMER
:
101 if (cmd
.val
< MIN_AdvRetransTimer
|| cmd
.val
> MAX_AdvRetransTimer
) {
102 flog(LOG_ERR
, "(privsep) %s: RetransTimer (%u) is not within the defined bounds, ignoring", cmd
.iface
, cmd
.val
);
105 ret
= set_interface_var(cmd
.iface
, PROC_SYS_IP6_RETRANSTIMER_MS
, "RetransTimer (ms)", cmd
.val
);
108 set_interface_var(cmd
.iface
, PROC_SYS_IP6_RETRANSTIMER
, "RetransTimer", cmd
.val
/ 1000 * USER_HZ
); /* XXX user_hz */
118 /* Return 1 if privsep is currently enabled */
120 privsep_enabled(void)
127 /* Fork to create privileged process connected by a pipe */
134 if (privsep_enabled())
137 if (pipe(pipefds
) != 0) {
138 flog(LOG_ERR
, "Couldn't create privsep pipe.");
144 flog(LOG_ERR
, "Couldn't fork for privsep.");
151 /* This will be the privileged child */
155 /* Detach from stdio */
156 nullfd
= open("/dev/null", O_RDONLY
);
164 /* XXX: we'll keep stderr open in debug mode for better logging */
165 if (get_debuglevel() == 0)
170 flog(LOG_ERR
, "Exiting, privsep_read_loop is complete.\n");
174 /* Continue execution (will drop privileges soon) */
181 /* Interface calls for the unprivileged process */
183 privsep_interface_linkmtu(const char *iface
, uint32_t mtu
)
185 struct privsep_command cmd
;
186 cmd
.type
= SET_INTERFACE_LINKMTU
;
187 strncpy(cmd
.iface
, iface
, sizeof(cmd
.iface
));
190 if (writen(pfd
, &cmd
, sizeof(cmd
)) != sizeof(cmd
))
196 privsep_interface_curhlim(const char *iface
, uint32_t hlim
)
198 struct privsep_command cmd
;
199 cmd
.type
= SET_INTERFACE_CURHLIM
;
200 strncpy(cmd
.iface
, iface
, sizeof(cmd
.iface
));
202 if (writen(pfd
, &cmd
, sizeof(cmd
)) != sizeof(cmd
))
208 privsep_interface_reachtime(const char *iface
, uint32_t rtime
)
210 struct privsep_command cmd
;
211 cmd
.type
= SET_INTERFACE_REACHTIME
;
212 strncpy(cmd
.iface
, iface
, sizeof(cmd
.iface
));
214 if (writen(pfd
, &cmd
, sizeof(cmd
)) != sizeof(cmd
))
220 privsep_interface_retranstimer(const char *iface
, uint32_t rettimer
)
222 struct privsep_command cmd
;
223 cmd
.type
= SET_INTERFACE_RETRANSTIMER
;
224 strncpy(cmd
.iface
, iface
, sizeof(cmd
.iface
));
226 if (writen(pfd
, &cmd
, sizeof(cmd
)) != sizeof(cmd
))