Skip to content

Commit 4db74b3

Browse files
committed
pppd: Check CAP_NET_RAW capability on Linux rather than requiring euid 0
Introduce USE_LIBCAP option turned on by default for the linux build. Provide an option to check that we are capable to admin the network wihout root via CAP_NET_RAW libcap option. Requires libcap library. Fallback to geteuid method in case of Solaris and Linux without libcap. Signed-off-by: Alexey Andreev <a.andreev@omprussia.ru>
1 parent 952cfa5 commit 4db74b3

5 files changed

Lines changed: 67 additions & 4 deletions

File tree

pppd/Makefile.linux

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ PLUGIN=y
7979
# Enable EAP SRP-SHA1 authentication (requires libsrp)
8080
#USE_SRP=y
8181

82+
# Use libcap (requires libcap)
83+
#USE_LIBCAP=y
84+
8285
# Use libutil; test if logwtmp is declared in <utmp.h> to detect
8386
ifeq ($(shell echo '\#include <utmp.h>' | $(CC) -E - 2>/dev/null | grep -q logwtmp && echo yes),yes)
8487
USE_LIBUTIL=y
@@ -148,6 +151,11 @@ CFLAGS += -DHAVE_CRYPT_H=1
148151
LIBS += -lcrypt
149152
endif
150153

154+
ifdef USE_LIBCAP
155+
CFLAGS += -DUSE_CAP
156+
LIBS += -lcap
157+
endif
158+
151159
ifdef USE_LIBUTIL
152160
CFLAGS += -DHAVE_LOGWTMP=1
153161
LIBS += -lutil

pppd/main.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -360,11 +360,10 @@ main(int argc, char *argv[])
360360
setlogmask(LOG_UPTO(LOG_DEBUG));
361361

362362
/*
363-
* Check that we are running as root.
363+
* Check that we are capable to admin the network.
364364
*/
365-
if (geteuid() != 0) {
366-
option_error("must be root to run %s, since it is not setuid-root",
367-
argv[0]);
365+
if (!net_capable()) {
366+
option_error("must have CAP_NET_RAW or root privilege to run %s", argv[0]);
368367
exit(EXIT_NOT_ROOT);
369368
}
370369

pppd/pppd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,7 @@ void sys_init(void); /* Do system-dependent initialization */
622622
void sys_cleanup(void); /* Restore system state before exiting */
623623
int sys_check_options(void); /* Check options specified */
624624
void sys_close(void); /* Clean up in a child before execing */
625+
int net_capable((void)); /* Test for any access to the net management */
625626
int ppp_available(void); /* Test whether ppp kernel support exists */
626627
int get_pty(int *, int *, char *, int); /* Get pty master/slave */
627628
int open_ppp_loopback(void); /* Open loopback for demand-dialling */

pppd/sys-linux.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,11 @@
144144
#include <sys/locks.h>
145145
#endif
146146

147+
#ifdef USE_CAP
148+
#include <sys/types.h>
149+
#include <sys/capability.h>
150+
#endif /* USE_CAP */
151+
147152
#ifdef INET6
148153
#ifndef _LINUX_IN6_H
149154
/*
@@ -2329,6 +2334,42 @@ ppp_registered(void)
23292334
return ret;
23302335
}
23312336

2337+
/***********************************************************
2338+
*
2339+
* net_capable - check for any access to the net management
2340+
*/
2341+
2342+
int net_capable(void)
2343+
{
2344+
int ok = 0;
2345+
#ifdef USE_CAP
2346+
/*
2347+
* Check that we are capable to admin the network.
2348+
*/
2349+
cap_t cap;
2350+
cap_flag_value_t cap_flag_value;
2351+
cap = cap_get_pid(getpid());
2352+
if (cap != 0) {
2353+
if (cap_get_flag(cap, CAP_NET_RAW, CAP_EFFECTIVE, &cap_flag_value) == 0) {
2354+
if (cap_flag_value == CAP_SET)
2355+
ok = 1;
2356+
}
2357+
if (cap_get_flag(cap, CAP_NET_RAW, CAP_PERMITTED, &cap_flag_value) == 0) {
2358+
if (cap_flag_value == CAP_SET)
2359+
ok = 1;
2360+
}
2361+
}
2362+
#else /* USE_CAP */
2363+
/*
2364+
* Check that we are running as root.
2365+
*/
2366+
if (geteuid() == 0) {
2367+
ok = 1;
2368+
}
2369+
#endif /* USE_CAP */
2370+
return ok;
2371+
}
2372+
23322373
/********************************************************************
23332374
*
23342375
* ppp_available - check whether the system has any ppp interfaces

pppd/sys-solaris.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,20 @@ daemon(int nochdir, int noclose)
852852
}
853853
#endif
854854

855+
/***********************************************************
856+
*
857+
* net_capable - check for any access to the net management
858+
*/
859+
860+
int net_capable(void)
861+
{
862+
int ok = 0;
863+
if (geteuid() == 0) {
864+
ok = 1;
865+
}
866+
return ok;
867+
}
868+
855869
/*
856870
* ppp_available - check whether the system has any ppp interfaces
857871
*/

0 commit comments

Comments
 (0)