diff options
Diffstat (limited to 'sys-utils/setpriv.c')
| -rw-r--r-- | sys-utils/setpriv.c | 63 |
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); |
