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.

Reply via email to