Adding support for the native Linux capabilities interface.

Note that this interface is deprecated and mainly added to support
Android. Use libcap, if possible.
This commit is contained in:
Tobias Brunner
2010-06-15 19:58:30 +02:00
parent b77e493bea
commit 946be4d357
4 changed files with 83 additions and 22 deletions
+31 -8
View File
@@ -22,8 +22,11 @@
#include <syslog.h>
#include <time.h>
#include <errno.h>
#ifdef CAPABILITIES
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif /* HAVE_SYS_CAPABILITY_H */
#endif /* CAPABILITIES */
#include "daemon.h"
@@ -46,12 +49,16 @@ struct private_daemon_t {
*/
daemon_t public;
#ifdef CAPABILITIES
/**
* capabilities to keep
*/
#ifdef CAPABILITIES_LIBCAP
cap_t caps;
#endif /* CAPABILITIES */
#endif /* CAPABILITIES_LIBCAP */
#ifdef CAPABILITIES_NATIVE
struct __user_cap_data_struct caps;
#endif /* CAPABILITIES_NATIVE */
};
/**
@@ -99,9 +106,9 @@ static void destroy(private_daemon_t *this)
DESTROY_IF(this->public.receiver);
/* unload plugins to release threads */
lib->plugins->unload(lib->plugins);
#ifdef CAPABILITIES
#ifdef CAPABILITIES_LIBCAP
cap_free(this->caps);
#endif /* CAPABILITIES */
#endif /* CAPABILITIES_LIBCAP */
DESTROY_IF(this->public.traps);
DESTROY_IF(this->public.ike_sa_manager);
DESTROY_IF(this->public.kernel_interface);
@@ -133,22 +140,36 @@ static void destroy(private_daemon_t *this)
METHOD(daemon_t, keep_cap, void,
private_daemon_t *this, u_int cap)
{
#ifdef CAPABILITIES
#ifdef CAPABILITIES_LIBCAP
cap_set_flag(this->caps, CAP_EFFECTIVE, 1, &cap, CAP_SET);
cap_set_flag(this->caps, CAP_INHERITABLE, 1, &cap, CAP_SET);
cap_set_flag(this->caps, CAP_PERMITTED, 1, &cap, CAP_SET);
#endif /* CAPABILITIES */
#endif /* CAPABILITIES_LIBCAP */
#ifdef CAPABILITIES_NATIVE
this->caps.effective |= 1 << cap;
this->caps.permitted |= 1 << cap;
this->caps.inheritable |= 1 << cap;
#endif /* CAPABILITIES_NATIVE */
}
METHOD(daemon_t, drop_capabilities, bool,
private_daemon_t *this)
{
#ifdef CAPABILITIES
#ifdef CAPABILITIES_LIBCAP
if (cap_set_proc(this->caps) != 0)
{
return FALSE;
}
#endif /* CAPABILITIES */
#endif /* CAPABILITIES_LIBCAP */
#ifdef CAPABILITIES_NATIVE
struct __user_cap_header_struct header = {
.version = _LINUX_CAPABILITY_VERSION,
};
if (capset(&header, &this->caps) != 0)
{
return FALSE;
}
#endif /* CAPABILITIES_NATIVE */
return TRUE;
}
@@ -397,7 +418,9 @@ private_daemon_t *daemon_create()
);
#ifdef CAPABILITIES
#ifdef CAPABILITIES_LIBCAP
this->caps = cap_init();
#endif /* CAPABILITIES_LIBCAP */
keep_cap(this, CAP_NET_ADMIN);
if (lib->leak_detective)
{
+35 -11
View File
@@ -33,7 +33,9 @@
#include <grp.h>
#ifdef CAPABILITIES
#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
#endif /* HAVE_SYS_CAPABILITY_H */
#endif /* CAPABILITIES */
#include <freeswan.h>
@@ -258,7 +260,6 @@ int main(int argc, char **argv)
char *virtual_private = NULL;
int lockfd;
#ifdef CAPABILITIES
cap_t caps;
int keep[] = { CAP_NET_ADMIN, CAP_NET_BIND_SERVICE };
#endif /* CAPABILITIES */
@@ -716,18 +717,41 @@ int main(int argc, char **argv)
}
#endif
#ifdef CAPABILITIES
caps = cap_init();
cap_set_flag(caps, CAP_EFFECTIVE, 2, keep, CAP_SET);
cap_set_flag(caps, CAP_INHERITABLE, 2, keep, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, 2, keep, CAP_SET);
if (cap_set_proc(caps) != 0)
#ifdef CAPABILITIES_LIBCAP
{
plog("unable to drop daemon capabilities");
abort();
cap_t caps;
caps = cap_init();
cap_set_flag(caps, CAP_EFFECTIVE, countof(keep), keep, CAP_SET);
cap_set_flag(caps, CAP_INHERITABLE, countof(keep), keep, CAP_SET);
cap_set_flag(caps, CAP_PERMITTED, countof(keep), keep, CAP_SET);
if (cap_set_proc(caps) != 0)
{
plog("unable to drop daemon capabilities");
abort();
}
cap_free(caps);
}
cap_free(caps);
#endif /* CAPABILITIES */
#endif /* CAPABILITIES_LIBCAP */
#ifdef CAPABILITIES_NATIVE
{
struct __user_cap_data_struct caps = { .effective = 0 };
struct __user_cap_header_struct header = {
.version = _LINUX_CAPABILITY_VERSION,
};
int i;
for (i = 0; i < countof(keep); i++)
{
caps.effective |= 1 << keep[i];
caps.permitted |= 1 << keep[i];
caps.inheritable |= 1 << keep[i];
}
if (capset(&header, &caps) != 0)
{
plog("unable to drop daemon capabilities");
abort();
}
}
#endif /* CAPABILITIES_NATIVE */
/* loading X.509 CA certificates */
load_authcerts("ca", CA_CERT_PATH, X509_CA);