summaryrefslogtreecommitdiff
path: root/sys-utils/setpriv.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys-utils/setpriv.c')
-rw-r--r--sys-utils/setpriv.c63
1 files changed, 42 insertions, 21 deletions
diff --git a/sys-utils/setpriv.c b/sys-utils/setpriv.c
index a547fd7ca..7bea62649 100644
--- a/sys-utils/setpriv.c
+++ b/sys-utils/setpriv.c
@@ -23,10 +23,12 @@
#include <getopt.h>
#include <grp.h>
#include <linux/securebits.h>
+#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/prctl.h>
+#include <sys/types.h>
#include <unistd.h>
#include "c.h"
@@ -104,8 +106,8 @@ static void __attribute__((__noreturn__)) usage(FILE *out)
fputs(_(" --keep-groups keep supplementary groups\n"), out);
fputs(_(" --groups <group,...> set supplementary groups\n"), out);
fputs(_(" --securebits <bits> set securebits\n"), out);
- fputs(_(" --selinux-label <label> set SELinux label (requires process:transition)\n"), out);
- fputs(_(" --apparmor-profile <pr> set AppArmor profile (requires onexec permission)\n"), out);
+ fputs(_(" --selinux-label <label> set SELinux label\n"), out);
+ fputs(_(" --apparmor-profile <pr> set AppArmor profile\n"), out);
fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
fputs(USAGE_VERSION, out);
@@ -228,7 +230,7 @@ static void dump_label(const char *name)
close(fd);
if (len < 0) {
errno = e;
- warn(_("read failed: %s"), name);
+ warn(_("cannot read %s"), name);
return;
}
if (sizeof(buf) - 1 <= (size_t)len) {
@@ -524,7 +526,9 @@ static void do_selinux_label(const char *label)
err(SETPRIV_EXIT_PRIVERR,
_("write failed: %s"), _PATH_PROC_ATTR_EXEC);
- close(fd);
+ if (close_fd(fd) != 0)
+ err(SETPRIV_EXIT_PRIVERR,
+ _("write failed: %s"), _PATH_PROC_ATTR_EXEC);
}
static void do_apparmor_profile(const char *label)
@@ -534,17 +538,40 @@ static void do_apparmor_profile(const char *label)
if (access(_PATH_SYS_APPARMOR, F_OK) != 0)
errx(SETPRIV_EXIT_PRIVERR, _("AppArmor is not running"));
- f = fopen(_PATH_PROC_ATTR_EXEC, "wx");
+ f = fopen(_PATH_PROC_ATTR_EXEC, "r+");
if (!f)
err(SETPRIV_EXIT_PRIVERR,
_("cannot open %s"), _PATH_PROC_ATTR_EXEC);
- if (fprintf(f, "changeprofile %s", label) < 0 || fflush(f) != 0
- || fclose(f) != 0)
+ fprintf(f, "exec %s", label);
+
+ if (close_stream(f) != 0)
err(SETPRIV_EXIT_PRIVERR,
_("write failed: %s"), _PATH_PROC_ATTR_EXEC);
}
+static uid_t get_user(const char *s, const char *err)
+{
+ struct passwd *pw;
+ long tmp;
+ pw = getpwnam(s);
+ if (pw)
+ return pw->pw_uid;
+ tmp = strtol_or_err(s, err);
+ return tmp;
+}
+
+static gid_t get_group(const char *s, const char *err)
+{
+ struct group *gr;
+ long tmp;
+ gr = getgrnam(s);
+ if (gr)
+ return gr->gr_gid;
+ tmp = strtol_or_err(s, err);
+ return tmp;
+}
+
int main(int argc, char **argv)
{
enum {
@@ -603,7 +630,7 @@ int main(int argc, char **argv)
int total_opts = 0;
int list_caps = 0;
- setlocale(LC_MESSAGES, "");
+ setlocale(LC_ALL, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
atexit(close_stdout);
@@ -627,43 +654,37 @@ int main(int argc, char **argv)
if (opts.have_ruid)
errx(EXIT_FAILURE, _("duplicate ruid"));
opts.have_ruid = 1;
- opts.ruid = strtol_or_err(optarg,
- _("failed to parse ruid"));
+ opts.ruid = get_user(optarg, _("failed to parse ruid"));
break;
case EUID:
if (opts.have_euid)
errx(EXIT_FAILURE, _("duplicate euid"));
opts.have_euid = 1;
- opts.euid = strtol_or_err(optarg,
- _("failed to parse euid"));
+ opts.euid = get_user(optarg, _("failed to parse euid"));
break;
case REUID:
if (opts.have_ruid || opts.have_euid)
errx(EXIT_FAILURE, _("duplicate ruid or euid"));
opts.have_ruid = opts.have_euid = 1;
- opts.ruid = opts.euid = strtol_or_err(optarg,
- _("failed to parse reuid"));
+ opts.ruid = opts.euid = get_user(optarg, _("failed to parse reuid"));
break;
case RGID:
if (opts.have_rgid)
errx(EXIT_FAILURE, _("duplicate rgid"));
opts.have_rgid = 1;
- opts.rgid = strtol_or_err(optarg,
- _("failed to parse rgid"));
+ opts.rgid = get_group(optarg, _("failed to parse rgid"));
break;
case EGID:
if (opts.have_egid)
errx(EXIT_FAILURE, _("duplicate egid"));
opts.have_egid = 1;
- opts.egid = strtol_or_err(optarg,
- _("failed to parse egid"));
+ opts.egid = get_group(optarg, _("failed to parse egid"));
break;
case REGID:
if (opts.have_rgid || opts.have_egid)
errx(EXIT_FAILURE, _("duplicate rgid or egid"));
opts.have_rgid = opts.have_egid = 1;
- opts.rgid = opts.egid = strtol_or_err(optarg,
- _("failed to parse regid"));
+ opts.rgid = opts.egid = get_group(optarg, _("failed to parse regid"));
break;
case CLEAR_GROUPS:
if (opts.clear_groups)
@@ -793,7 +814,7 @@ int main(int argc, char **argv)
if (opts.have_securebits)
if (prctl(PR_SET_SECUREBITS, opts.securebits, 0, 0, 0) != 0)
- err(SETPRIV_EXIT_PRIVERR, _("set procecess securebits failed"));
+ err(SETPRIV_EXIT_PRIVERR, _("set process securebits failed"));
if (opts.bounding_set) {
do_caps(CAPNG_BOUNDING_SET, opts.bounding_set);