Skip to content

Commit 722f326

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 049d5b8 commit 722f326

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
@@ -78,6 +78,9 @@ PLUGIN=y
7878
# Enable EAP SRP-SHA1 authentication (requires libsrp)
7979
#USE_SRP=y
8080

81+
# Use libcap (requires libcap)
82+
USE_LIBCAP=y
83+
8184
# Use libutil
8285
USE_LIBUTIL=y
8386

@@ -145,6 +148,11 @@ CFLAGS += -DHAVE_CRYPT_H=1
145148
LIBS += -lcrypt
146149
endif
147150

151+
ifdef USE_LIBCAP
152+
CFLAGS += -DUSE_CAP
153+
LIBS += -lcap
154+
endif
155+
148156
ifdef USE_LIBUTIL
149157
CFLAGS += -DHAVE_LOGWTMP=1
150158
LIBS += -lutil

pppd/main.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,11 +370,10 @@ main(argc, argv)
370370
setlogmask(LOG_UPTO(LOG_DEBUG));
371371

372372
/*
373-
* Check that we are running as root.
373+
* Check that we are capable to admin the network.
374374
*/
375-
if (geteuid() != 0) {
376-
option_error("must be root to run %s, since it is not setuid-root",
377-
argv[0]);
375+
if (!net_capable()) {
376+
option_error("must have CAP_NET_RAW or root privilege to run %s", argv[0]);
378377
exit(EXIT_NOT_ROOT);
379378
}
380379

pppd/pppd.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,7 @@ void sys_init __P((void)); /* Do system-dependent initialization */
630630
void sys_cleanup __P((void)); /* Restore system state before exiting */
631631
int sys_check_options __P((void)); /* Check options specified */
632632
void sys_close __P((void)); /* Clean up in a child before execing */
633+
int net_capable __P((void)); /* Test for any access to the net management */
633634
int ppp_available __P((void)); /* Test whether ppp kernel support exists */
634635
int get_pty __P((int *, int *, char *, int)); /* Get pty master/slave */
635636
int open_ppp_loopback __P((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
/*
@@ -2242,6 +2247,42 @@ ppp_registered(void)
22422247
return ret;
22432248
}
22442249

2250+
/***********************************************************
2251+
*
2252+
* net_capable - check for any access to the net management
2253+
*/
2254+
2255+
int net_capable(void)
2256+
{
2257+
int ok = 0;
2258+
#ifdef USE_CAP
2259+
/*
2260+
* Check that we are capable to admin the network.
2261+
*/
2262+
cap_t cap;
2263+
cap_flag_value_t cap_flag_value;
2264+
cap = cap_get_pid(getpid());
2265+
if (cap != 0) {
2266+
if (cap_get_flag(cap, CAP_NET_RAW, CAP_EFFECTIVE, &cap_flag_value) == 0) {
2267+
if (cap_flag_value == CAP_SET)
2268+
ok = 1;
2269+
}
2270+
if (cap_get_flag(cap, CAP_NET_RAW, CAP_PERMITTED, &cap_flag_value) == 0) {
2271+
if (cap_flag_value == CAP_SET)
2272+
ok = 1;
2273+
}
2274+
}
2275+
#else /* USE_CAP */
2276+
/*
2277+
* Check that we are running as root.
2278+
*/
2279+
if (geteuid() == 0) {
2280+
ok = 1;
2281+
}
2282+
#endif /* USE_CAP */
2283+
return ok;
2284+
}
2285+
22452286
/********************************************************************
22462287
*
22472288
* 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
@@ -904,6 +904,20 @@ daemon(nochdir, noclose)
904904
}
905905
#endif
906906

907+
/***********************************************************
908+
*
909+
* net_capable - check for any access to the net management
910+
*/
911+
912+
int net_capable(void)
913+
{
914+
int ok = 0;
915+
if (geteuid() == 0) {
916+
ok = 1;
917+
}
918+
return ok;
919+
}
920+
907921
/*
908922
* ppp_available - check whether the system has any ppp interfaces
909923
*/

0 commit comments

Comments
 (0)