On Tue, May 17, 2016 at 01:45:18PM +0200, Silamael wrote:
> Since OpenBSD 5.9 it's no longer possible to run skeyinit for another
> user while being root:
>
> root@testpc:~# skeyinit -md5 admin
> [Adding admin with md5]
> skeyinit: can't set owner/mode for admin: Operation not permitted
>
> As far as I unterstand the check in pledge_chown() in kern_pledge.c is
> preventing this.
Thanks for the report.
I agree with your diagnosis. skeyinit tries to fchown the file to the
target user and gets EPERM since it is running with pledge.
Here's a patch that disables pledge for skeyinit if it is run as root
and there is a target user specified. It should be possible to pledge
after the fchown() call, but I haven't had the time to investigate this,
yet.
Index: skeyinit.c
===================================================================
RCS file: /var/cvs/src/usr.bin/skeyinit/skeyinit.c,v
retrieving revision 1.69
diff -u -p -r1.69 skeyinit.c
--- skeyinit.c 21 Feb 2016 22:53:40 -0000 1.69
+++ skeyinit.c 17 May 2016 13:59:35 -0000
@@ -46,7 +46,7 @@ void enable_db(int);
int
main(int argc, char **argv)
{
- int rval, i, l, n, defaultsetup, rmkey, hexmode, enable;
+ int rval, i, l, n, defaultsetup, rmkey, hexmode, enable, canpledge;
char hostname[HOST_NAME_MAX+1];
char seed[SKEY_MAX_SEED_LEN + 1];
char buf[256], key[SKEY_BINKEY_SIZE], filename[PATH_MAX], *ht;
@@ -117,9 +117,13 @@ main(int argc, char **argv)
exit(0);
}
- if (pledge("stdio rpath wpath cpath fattr flock tty proc exec getpw",
- NULL) == -1)
- err(1, "pledge");
+ canpledge = (argc == 0 || getuid() != 0);
+
+ if (canpledge) {
+ if (pledge("stdio rpath wpath cpath fattr flock tty proc exec "
+ "getpw", NULL) == -1)
+ err(1, "pledge");
+ }
/* Build up a default seed based on the hostname and some randomness */
if (gethostname(hostname, sizeof(hostname)) < 0)
@@ -186,8 +190,10 @@ main(int argc, char **argv)
errx(1, "Password incorrect");
}
- if (pledge("stdio rpath wpath cpath fattr flock tty", NULL) == -1)
- err(1, "pledge");
+ if (canpledge)
+ if (pledge("stdio rpath wpath cpath fattr flock tty", NULL)
+ == -1)
+ err(1, "pledge");
/*
* Lookup and lock the record we are about to modify.