capabilities: Add support for Linux capabilities(7)
This adds capabilities for start-stop-daemon by adding --capabilities option. As a result, the user can specify the inheritable, ambient and bounding set by define capabilities in the service script. This fixes #314.
This commit is contained in:
@@ -93,9 +93,9 @@ executable('runscript',
|
||||
executable('start-stop-daemon',
|
||||
['start-stop-daemon.c', 'rc-pipes.c', rc_misc_c, rc_schedules_c,
|
||||
rc_selinux_c, usage_c, version_h],
|
||||
c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_selinux_flags],
|
||||
c_args : [cc_audit_flags, cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
|
||||
link_with: [libeinfo, librc],
|
||||
dependencies: [audit_dep, dl_dep, pam_dep, pam_misc_dep, util_dep, selinux_dep, crypt_dep],
|
||||
dependencies: [audit_dep, dl_dep, pam_dep, cap_dep, pam_misc_dep, util_dep, selinux_dep, crypt_dep],
|
||||
include_directories: [incdir, einfo_incdir, rc_incdir],
|
||||
install: true,
|
||||
install_dir: sbindir)
|
||||
@@ -103,9 +103,9 @@ executable('start-stop-daemon',
|
||||
executable('supervise-daemon',
|
||||
['supervise-daemon.c', rc_misc_c, rc_plugin_c, rc_schedules_c,
|
||||
usage_c, version_h],
|
||||
c_args : [cc_branding_flags, cc_pam_flags, cc_selinux_flags],
|
||||
c_args : [cc_branding_flags, cc_pam_flags, cc_cap_flags, cc_selinux_flags],
|
||||
link_with: [libeinfo, librc],
|
||||
dependencies: [dl_dep, pam_dep, util_dep, selinux_dep],
|
||||
dependencies: [dl_dep, pam_dep, cap_dep, util_dep, selinux_dep],
|
||||
include_directories: [incdir, einfo_incdir, rc_incdir],
|
||||
install: true,
|
||||
install_dir: sbindir)
|
||||
|
@@ -55,6 +55,10 @@
|
||||
static struct pam_conv conv = { NULL, NULL};
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CAP
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
@@ -69,6 +73,7 @@ const char *extraopts = NULL;
|
||||
const char getoptstring[] = "I:KN:PR:Sa:bc:d:e:g:ik:mn:op:s:tu:r:w:x:1:2:3:4:" \
|
||||
getoptstring_COMMON;
|
||||
const struct option longopts[] = {
|
||||
{ "capabilities", 1, NULL, 0x100},
|
||||
{ "ionice", 1, NULL, 'I'},
|
||||
{ "stop", 0, NULL, 'K'},
|
||||
{ "nicelevel", 1, NULL, 'N'},
|
||||
@@ -101,6 +106,7 @@ const struct option longopts[] = {
|
||||
longopts_COMMON
|
||||
};
|
||||
const char * const longopts_help[] = {
|
||||
"Set the inheritable, ambient and bounding capabilities",
|
||||
"Set an ionice class:data when starting",
|
||||
"Stop daemon",
|
||||
"Set a nicelevel when starting",
|
||||
@@ -307,6 +313,9 @@ int main(int argc, char **argv)
|
||||
mode_t numask = 022;
|
||||
char **margv;
|
||||
unsigned int start_wait = 0;
|
||||
#ifdef HAVE_CAP
|
||||
cap_iab_t cap_iab = NULL;
|
||||
#endif
|
||||
|
||||
applet = basename_c(argv[0]);
|
||||
atexit(cleanup);
|
||||
@@ -353,6 +362,16 @@ int main(int argc, char **argv)
|
||||
while ((opt = getopt_long(argc, argv, getoptstring, longopts,
|
||||
(int *) 0)) != -1)
|
||||
switch (opt) {
|
||||
case 0x100:
|
||||
#ifdef HAVE_CAP
|
||||
cap_iab = cap_iab_from_text(optarg);
|
||||
if (cap_iab == NULL)
|
||||
eerrorx("Could not parse iab: %s", strerror(errno));
|
||||
#else
|
||||
eerrorx("Capabilities support not enabled");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'I': /* --ionice */
|
||||
if (sscanf(optarg, "%d:%d", &ionicec, &ioniced) == 0)
|
||||
eerrorx("%s: invalid ionice `%s'",
|
||||
@@ -850,13 +869,29 @@ int main(int argc, char **argv)
|
||||
if (changeuser && initgroups(changeuser, gid))
|
||||
eerrorx("%s: initgroups (%s, %d)",
|
||||
applet, changeuser, gid);
|
||||
#ifdef HAVE_CAP
|
||||
if (uid && cap_setuid(uid))
|
||||
#else
|
||||
if (uid && setuid(uid))
|
||||
#endif
|
||||
eerrorx ("%s: unable to set userid to %d",
|
||||
applet, uid);
|
||||
|
||||
/* Close any fd's to the passwd database */
|
||||
endpwent();
|
||||
|
||||
#ifdef HAVE_CAP
|
||||
if (cap_iab != NULL) {
|
||||
i = cap_iab_set_proc(cap_iab);
|
||||
|
||||
if (cap_free(cap_iab) != 0)
|
||||
eerrorx("Could not releasable memory: %s", strerror(errno));
|
||||
|
||||
if (i != 0)
|
||||
eerrorx("Could not set iab: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TIOCNOTTY
|
||||
ioctl(tty_fd, TIOCNOTTY, 0);
|
||||
close(tty_fd);
|
||||
|
@@ -57,6 +57,10 @@
|
||||
static struct pam_conv conv = { NULL, NULL};
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CAP
|
||||
#include <sys/capability.h>
|
||||
#endif
|
||||
|
||||
#include "einfo.h"
|
||||
#include "queue.h"
|
||||
#include "rc.h"
|
||||
@@ -73,6 +77,7 @@ const char getoptstring[] = "A:a:D:d:e:g:H:I:Kk:m:N:p:R:r:s:Su:1:2:3" \
|
||||
const struct option longopts[] = {
|
||||
{ "healthcheck-timer", 1, NULL, 'a'},
|
||||
{ "healthcheck-delay", 1, NULL, 'A'},
|
||||
{ "capabilities", 1, NULL, 0x100},
|
||||
{ "respawn-delay", 1, NULL, 'D'},
|
||||
{ "chdir", 1, NULL, 'd'},
|
||||
{ "env", 1, NULL, 'e'},
|
||||
@@ -98,6 +103,7 @@ const struct option longopts[] = {
|
||||
const char * const longopts_help[] = {
|
||||
"set an initial health check delay",
|
||||
"set a health check timer",
|
||||
"Set the inheritable, ambient and bounding capabilities",
|
||||
"Set a respawn delay",
|
||||
"Change the PWD",
|
||||
"Set an environment string",
|
||||
@@ -152,6 +158,9 @@ static int fifo_fd = 0;
|
||||
static char *pidfile = NULL;
|
||||
static char *svcname = NULL;
|
||||
static bool verbose = false;
|
||||
#ifdef HAVE_CAP
|
||||
static cap_iab_t cap_iab = NULL;
|
||||
#endif
|
||||
|
||||
extern char **environ;
|
||||
|
||||
@@ -398,12 +407,28 @@ static void child_process(char *exec, char **argv)
|
||||
eerrorx("%s: unable to set groupid to %d", applet, gid);
|
||||
if (changeuser && initgroups(changeuser, gid))
|
||||
eerrorx("%s: initgroups (%s, %d)", applet, changeuser, gid);
|
||||
#ifdef HAVE_CAP
|
||||
if (uid && cap_setuid(uid))
|
||||
#else
|
||||
if (uid && setuid(uid))
|
||||
#endif
|
||||
eerrorx ("%s: unable to set userid to %d", applet, uid);
|
||||
|
||||
/* Close any fd's to the passwd database */
|
||||
endpwent();
|
||||
|
||||
#ifdef HAVE_CAP
|
||||
if (cap_iab != NULL) {
|
||||
i = cap_iab_set_proc(cap_iab);
|
||||
|
||||
if (cap_free(cap_iab) != 0)
|
||||
eerrorx("Could not releasable memory: %s", strerror(errno));
|
||||
|
||||
if (i != 0)
|
||||
eerrorx("Could not set iab: %s", strerror(errno));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* remove the controlling tty */
|
||||
#ifdef TIOCNOTTY
|
||||
ioctl(tty_fd, TIOCNOTTY, 0);
|
||||
@@ -797,6 +822,16 @@ int main(int argc, char **argv)
|
||||
eerrorx("%s: invalid health check delay %s", applet, optarg);
|
||||
break;
|
||||
|
||||
case 0x100:
|
||||
#ifdef HAVE_CAP
|
||||
cap_iab = cap_iab_from_text(optarg);
|
||||
if (cap_iab == NULL)
|
||||
eerrorx("Could not parse iab: %s", strerror(errno));
|
||||
#else
|
||||
eerrorx("Capabilities support not enabled");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'D': /* --respawn-delay time */
|
||||
n = sscanf(optarg, "%d", &respawn_delay);
|
||||
if (n != 1 || respawn_delay < 1)
|
||||
|
Reference in New Issue
Block a user