capability API to allow plugin-controlled capability set
This commit is contained in:
+29
-35
@@ -80,6 +80,11 @@ struct private_daemon_t {
|
|||||||
* The thread_id of main-thread.
|
* The thread_id of main-thread.
|
||||||
*/
|
*/
|
||||||
pthread_t main_thread_id;
|
pthread_t main_thread_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* capabilities to keep
|
||||||
|
*/
|
||||||
|
u_int32_t keep;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -247,41 +252,20 @@ static void kill_daemon(private_daemon_t *this, char *reason)
|
|||||||
/**
|
/**
|
||||||
* drop daemon capabilities
|
* drop daemon capabilities
|
||||||
*/
|
*/
|
||||||
static void drop_capabilities(private_daemon_t *this, bool full)
|
static void drop_capabilities(private_daemon_t *this)
|
||||||
{
|
{
|
||||||
struct __user_cap_header_struct hdr;
|
struct __user_cap_header_struct hdr;
|
||||||
struct __user_cap_data_struct data;
|
struct __user_cap_data_struct data;
|
||||||
|
|
||||||
/* CAP_NET_ADMIN is needed to use netlink,
|
prctl(PR_SET_KEEPCAPS, 1);
|
||||||
* CAP_AUDIT_WRITE for PAM authentication in EAP-GTC */
|
|
||||||
u_int32_t keep = (1<<CAP_NET_ADMIN) | (1<<CAP_SYS_NICE) |
|
if (setgid(charon->gid) != 0)
|
||||||
(1<<CAP_AUDIT_WRITE);
|
|
||||||
|
|
||||||
if (full)
|
|
||||||
{
|
{
|
||||||
if (setgid(charon->gid) != 0)
|
kill_daemon(this, "change to unprivileged group failed");
|
||||||
{
|
|
||||||
kill_daemon(this, "change to unprivileged group failed");
|
|
||||||
}
|
|
||||||
if (setuid(charon->uid) != 0)
|
|
||||||
{
|
|
||||||
kill_daemon(this, "change to unprivileged user failed");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
if (setuid(charon->uid) != 0)
|
||||||
{
|
{
|
||||||
/* CAP_NET_BIND_SERVICE to bind services below port 1024 */
|
kill_daemon(this, "change to unprivileged user failed");
|
||||||
keep |= (1<<CAP_NET_BIND_SERVICE);
|
|
||||||
/* CAP_NET_RAW to create RAW sockets */
|
|
||||||
keep |= (1<<CAP_NET_RAW);
|
|
||||||
/* CAP_DAC_READ_SEARCH to read ipsec.secrets */
|
|
||||||
keep |= (1<<CAP_DAC_READ_SEARCH);
|
|
||||||
/* CAP_CHOWN to change file permissions (socket permissions) */
|
|
||||||
keep |= (1<<CAP_CHOWN);
|
|
||||||
/* CAP_SETUID to call setuid() */
|
|
||||||
keep |= (1<<CAP_SETUID);
|
|
||||||
/* CAP_SETGID to call setgid() */
|
|
||||||
keep |= (1<<CAP_SETGID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we use the old capset version for now. For systems with version 2
|
/* we use the old capset version for now. For systems with version 2
|
||||||
@@ -292,7 +276,7 @@ static void drop_capabilities(private_daemon_t *this, bool full)
|
|||||||
hdr.version = _LINUX_CAPABILITY_VERSION;
|
hdr.version = _LINUX_CAPABILITY_VERSION;
|
||||||
#endif
|
#endif
|
||||||
hdr.pid = 0;
|
hdr.pid = 0;
|
||||||
data.inheritable = data.effective = data.permitted = keep;
|
data.inheritable = data.effective = data.permitted = this->keep;
|
||||||
|
|
||||||
if (capset(&hdr, &data))
|
if (capset(&hdr, &data))
|
||||||
{
|
{
|
||||||
@@ -300,6 +284,14 @@ static void drop_capabilities(private_daemon_t *this, bool full)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of daemon_t.keep_cap
|
||||||
|
*/
|
||||||
|
static void keep_cap(private_daemon_t *this, u_int cap)
|
||||||
|
{
|
||||||
|
this->keep |= 1 << cap;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lookup UID and GID
|
* lookup UID and GID
|
||||||
*/
|
*/
|
||||||
@@ -479,6 +471,7 @@ private_daemon_t *daemon_create(void)
|
|||||||
|
|
||||||
/* assign methods */
|
/* assign methods */
|
||||||
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
|
this->public.kill = (void (*) (daemon_t*,char*))kill_daemon;
|
||||||
|
this->public.keep_cap = (void(*)(daemon_t*, u_int cap))keep_cap;
|
||||||
|
|
||||||
/* NULL members for clean destruction */
|
/* NULL members for clean destruction */
|
||||||
this->public.socket = NULL;
|
this->public.socket = NULL;
|
||||||
@@ -505,6 +498,11 @@ private_daemon_t *daemon_create(void)
|
|||||||
this->public.gid = 0;
|
this->public.gid = 0;
|
||||||
|
|
||||||
this->main_thread_id = pthread_self();
|
this->main_thread_id = pthread_self();
|
||||||
|
this->keep = 1<<CAP_NET_ADMIN;
|
||||||
|
if (lib->leak_detective)
|
||||||
|
{
|
||||||
|
this->keep = 1<<CAP_SYS_NICE;
|
||||||
|
}
|
||||||
|
|
||||||
/* add handler for SEGV and ILL,
|
/* add handler for SEGV and ILL,
|
||||||
* add handler for USR1 (cancellation).
|
* add handler for USR1 (cancellation).
|
||||||
@@ -574,10 +572,6 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
lookup_uid_gid(private_charon);
|
lookup_uid_gid(private_charon);
|
||||||
|
|
||||||
/* drop the capabilities we won't need for initialization */
|
|
||||||
prctl(PR_SET_KEEPCAPS, 1);
|
|
||||||
drop_capabilities(private_charon, FALSE);
|
|
||||||
|
|
||||||
/* use CTRL loglevel for default */
|
/* use CTRL loglevel for default */
|
||||||
for (signal = 0; signal < DBG_MAX; signal++)
|
for (signal = 0; signal < DBG_MAX; signal++)
|
||||||
{
|
{
|
||||||
@@ -653,8 +647,8 @@ int main(int argc, char *argv[])
|
|||||||
fclose(pid_file);
|
fclose(pid_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* drop additional capabilites (bind & root) */
|
/* drop the capabilities we won't need */
|
||||||
drop_capabilities(private_charon, TRUE);
|
drop_capabilities(private_charon);
|
||||||
|
|
||||||
/* start the engine, go multithreaded */
|
/* start the engine, go multithreaded */
|
||||||
charon->processor->set_threads(charon->processor,
|
charon->processor->set_threads(charon->processor,
|
||||||
|
|||||||
@@ -302,6 +302,15 @@ struct daemon_t {
|
|||||||
*/
|
*/
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do not drop a given capability after initialization.
|
||||||
|
*
|
||||||
|
* Some plugins might need additional capabilites. They tell the daemon
|
||||||
|
* during plugin initialization which one they need, the daemon won't
|
||||||
|
* drop these.
|
||||||
|
*/
|
||||||
|
void (*keep_cap)(daemon_t *this, u_int cap);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shut down the daemon.
|
* Shut down the daemon.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
|
|
||||||
#include <daemon.h>
|
#include <daemon.h>
|
||||||
|
|
||||||
|
#include <linux/capability.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of plugin_t.destroy
|
* Implementation of plugin_t.destroy
|
||||||
*/
|
*/
|
||||||
@@ -42,6 +44,9 @@ plugin_t *plugin_create()
|
|||||||
|
|
||||||
this->plugin.destroy = (void(*)(plugin_t*))destroy;
|
this->plugin.destroy = (void(*)(plugin_t*))destroy;
|
||||||
|
|
||||||
|
/* required for PAM authentication */
|
||||||
|
charon->keep_cap(charon, CAP_AUDIT_WRITE);
|
||||||
|
|
||||||
charon->eap->add_method(charon->eap, EAP_GTC, 0, EAP_SERVER,
|
charon->eap->add_method(charon->eap, EAP_GTC, 0, EAP_SERVER,
|
||||||
(eap_constructor_t)eap_gtc_create_server);
|
(eap_constructor_t)eap_gtc_create_server);
|
||||||
charon->eap->add_method(charon->eap, EAP_GTC, 0, EAP_PEER,
|
charon->eap->add_method(charon->eap, EAP_GTC, 0, EAP_PEER,
|
||||||
|
|||||||
@@ -86,6 +86,8 @@ void library_init(char *settings)
|
|||||||
private_library_t *this = malloc_thing(private_library_t);
|
private_library_t *this = malloc_thing(private_library_t);
|
||||||
lib = &this->public;
|
lib = &this->public;
|
||||||
|
|
||||||
|
lib->leak_detective = FALSE;
|
||||||
|
|
||||||
#ifdef LEAK_DETECTIVE
|
#ifdef LEAK_DETECTIVE
|
||||||
this->detective = leak_detective_create();
|
this->detective = leak_detective_create();
|
||||||
#endif /* LEAK_DETECTIVE */
|
#endif /* LEAK_DETECTIVE */
|
||||||
|
|||||||
@@ -108,6 +108,11 @@ struct library_t {
|
|||||||
* various settings loaded from settings file
|
* various settings loaded from settings file
|
||||||
*/
|
*/
|
||||||
settings_t *settings;
|
settings_t *settings;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* is leak detective running?
|
||||||
|
*/
|
||||||
|
bool leak_detective;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -560,6 +560,7 @@ leak_detective_t *leak_detective_create()
|
|||||||
|
|
||||||
if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
|
if (getenv("LEAK_DETECTIVE_DISABLE") == NULL)
|
||||||
{
|
{
|
||||||
|
lib->leak_detective = TRUE;
|
||||||
install_hooks();
|
install_hooks();
|
||||||
}
|
}
|
||||||
return &this->public;
|
return &this->public;
|
||||||
|
|||||||
Reference in New Issue
Block a user