From: Karel Zak <kzak@redhat.com>
To: Andy Lutomirski <luto@amacapital.net>
Cc: util-linux@vger.kernel.org, "Pádraig Brady" <P@draigbrady.com>,
"Ángel González" <ingenit@zoho.com>
Subject: Re: [PATCH] Add setpriv, a tool to set privileges and such
Date: Tue, 8 Jan 2013 09:31:30 +0100 [thread overview]
Message-ID: <20130108083130.GA13020@x2.net.home> (raw)
In-Reply-To: <5a4bb50baed87dbe00be9003dad7cc1ba59ca571.1354954632.git.luto@amacapital.net>
Sorry for the delay, I had 3 weeks vacation.
On Sat, Dec 08, 2012 at 12:19:12AM -0800, Andy Lutomirski wrote:
> +if BUILD_SETPRIV
> +usrbin_exec_PROGRAMS += setpriv
> +dist_man_MANS += sys-utils/setpriv.1
> +setpriv_SOURCES = sys-utils/setpriv.c
> +setpriv_LDADD = -lcap-ng
> +endif
Maybe the caps support should be optional, anyway you need to check
for the library in the configure script.
> +static void complain(const char *fmt, ...)
> +{
> + va_list ap;
> + va_start(ap, fmt);
> + vfprintf(stderr, fmt, ap);
> + va_end(ap);
> + fputc('\n', stderr);
> + usage(EXIT_FAILURE);
> +}
seems like poor reimplementation of err() from err.h :-)
> +// Returns the number of capabilities printed
please use /* comment */
> +static void stdout_perror(const char *prefix)
> +{
> + if (errno < 0 || errno >= sys_nerr)
> + printf(_("%s: error %d\n"), prefix, errno);
> + else
> + printf(_("%s: %s\n"), prefix, sys_errlist[errno]);
> +}
warnx() from err.h
> +static void dump_label(const char *name)
> +{
> + int fd = open("/proc/self/attr/current", O_RDONLY);
> + if (fd == -1) {
> + stdout_perror(name);
> + return;
> + }
> +
> + char buf[4097];
> + ssize_t len = read(fd, buf, sizeof(buf));
> + int e = errno;
we usually have declarations at the begin of block (function)...
> +struct options {
...and structs at the begin of the file. The name "options" seems
also too generic (like anything for getopt_long), what about
struct privcxt {
}
or so.
> bool nnp;
don't use bool in util-linux, within structs you can use bit arrays.
> // real and effective (in that order)
> bool have_uid[2];
> uid_t uid[2];
> bool have_gid[2];
> gid_t gid[2];
it would be more readable to use
uid_t ruid;
uid_t euid;
unsigned have_ruid:1,
have_euid:1;
(and the same for groups) rather than depend on an order.
> +static void priverr(const char *str)
> +{
> + perror(str);
> + exit(127);
> +}
err(127, str);
it would be also nice to have a macro (SETPRV_EX_* ?) in the code
rather than the magic number.
> +
> +static void parse_groups(struct options *opts, const char *str)
> +{
> + char *groups = strdup(str);
> + char *buf = groups; /* We'll reuse it */
> + char *c;
> +
> + opts->have_groups = true;
> + opts->num_groups = 0;
> + while ((c = strsep(&groups, ",")) != 0)
> + opts->num_groups++;
> +
> + // Start again
> + strcpy(buf, str); // It's exactly the right length
> + groups = buf;
> +
> + opts->groups = calloc(opts->num_groups, sizeof(gid_t));
> + size_t i = 0;
> + while ((c = strsep(&groups, ",")) != 0) {
> + char *end;
> + errno = 0;
> + long val = strtol(c, &end, 10);
strtol_or_err() (include/strutils.h)
> + if (!*c || *end || errno || val != (long long)(gid_t)val)
> + complain(_("Invalid supplementary group id"));
> + opts->groups[i++] = (gid_t)val;
> + }
> +
> + free(groups);;
> +}
> +
> +int main(int argc, char *argv[])
> +{
> + enum {
> + NNP = 256,
SETPRIV_OPT_NNP = CHAR_MAX + 1
> + RUID = 256,
> + EUID,
> + RGID,
> + EGID,
> + REUID,
> + REGID,
> + CLEAR_GROUPS,
> + KEEP_GROUPS,
> + GROUPS,
> + INHCAPS,
> + LISTCAPS,
> + CAPBSET,
> + SECUREBITS,
> + SELINUX_LABEL,
> + APPARMOR_PROFILE
> + };
[...]
> + if (RUID <= c && c <= REGID) {
> + /* This is easier than six independent cases. */
> + char *end;
> + errno = 0;
> + long val = strtol(optarg, &end, 10);
> + if (!*optarg || errno || *end)
> + complain(_("Failed to parse uid or gid"));
> +
> + if (c == REUID) {
if (opts.have_euid)
err(EXIT_FAILURE, _("duplicate euid");
opts.have_euid = 1;
opts.euid = strtol_or_err(optarg, _("failed to parse euid");
... no loop, no arrays for uids, just readable code.
[..]
> + if (dumplevel) {
> + if (total_opts != dumplevel || optind < argc)
> + complain(_("--dump is incompatible with all other options"));
> + dump(dumplevel);
> + return 0;
this is main(), so return EXIT_SUCCES;
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
next prev parent reply other threads:[~2013-01-08 8:31 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-11-23 20:23 [PATCH] Add no_new_privs Andy Lutomirski
2012-11-23 21:14 ` Pádraig Brady
2012-11-26 10:08 ` Karel Zak
2012-11-26 12:45 ` Ángel González
2012-11-26 19:03 ` Andy Lutomirski
2012-11-27 1:39 ` Andy Lutomirski
2012-11-23 22:52 ` Ángel González
2012-12-08 8:19 ` [PATCH] Add setpriv, a tool to set privileges and such Andy Lutomirski
2012-12-08 16:23 ` Ángel González
2012-12-08 19:04 ` Andy Lutomirski
2012-12-09 22:24 ` Pádraig Brady
2012-12-09 23:12 ` Andy Lutomirski
2013-01-08 8:31 ` Karel Zak [this message]
2013-01-14 15:33 ` Andy Lutomirski
2013-01-14 15:58 ` [PATCH v2] " Andy Lutomirski
2013-01-26 14:29 ` [PATCH] setpriv: run a program with different Linux privilege settings Sami Kerola
2013-02-04 20:20 ` Andy Lutomirski
2013-02-05 9:05 ` Karel Zak
2013-02-05 10:51 ` Karel Zak
2013-02-06 1:07 ` [PATCH] setpriv: Fix an error message typo Andy Lutomirski
2013-02-06 11:32 ` Karel Zak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130108083130.GA13020@x2.net.home \
--to=kzak@redhat.com \
--cc=P@draigbrady.com \
--cc=ingenit@zoho.com \
--cc=luto@amacapital.net \
--cc=util-linux@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).