util-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).