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.