diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2016-08-16 04:55:34 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2016-08-16 04:55:34 +0000 |
commit | 0116acec88444194b55a1030ca1fc589ff710aa9 (patch) | |
tree | 6b61a83fa08fa65be7b820a61ba32f76f10f7403 /distrib/special/doas | |
parent | 1b8be5e55ff28c70b2914cffb96494b5e8ade707 (diff) |
add a special edition doas that only lets root drop privs.
maybe the installer can use something like this, wink wink.
ok deraadt
Diffstat (limited to 'distrib/special/doas')
-rw-r--r-- | distrib/special/doas/Makefile | 6 | ||||
-rw-r--r-- | distrib/special/doas/doas.c | 107 |
2 files changed, 113 insertions, 0 deletions
diff --git a/distrib/special/doas/Makefile b/distrib/special/doas/Makefile new file mode 100644 index 00000000000..ae95c24ed68 --- /dev/null +++ b/distrib/special/doas/Makefile @@ -0,0 +1,6 @@ +# $OpenBSD: Makefile,v 1.1 2016/08/16 04:55:33 tedu Exp $ + +PROG= doas +SRCS= doas.c + +.include <bsd.prog.mk> diff --git a/distrib/special/doas/doas.c b/distrib/special/doas/doas.c new file mode 100644 index 00000000000..42c4d80bbd0 --- /dev/null +++ b/distrib/special/doas/doas.c @@ -0,0 +1,107 @@ +/* $OpenBSD: doas.c,v 1.1 2016/08/16 04:55:33 tedu Exp $ */ +/* + * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/types.h> +#include <sys/stat.h> + +#include <limits.h> +#include <string.h> +#include <stdio.h> +#include <stdlib.h> +#include <err.h> +#include <unistd.h> +#include <pwd.h> +#include <grp.h> +#include <syslog.h> +#include <errno.h> + +static void __dead +usage(void) +{ + fprintf(stderr, "usage: doas [-u user] command [args]\n"); + exit(1); +} + +static int +parseuid(const char *s, uid_t *uid) +{ + struct passwd *pw; + const char *errstr; + + if ((pw = getpwnam(s)) != NULL) { + *uid = pw->pw_uid; + return 0; + } + *uid = strtonum(s, 0, UID_MAX, &errstr); + if (errstr) + return -1; + return 0; +} + +int +main(int argc, char **argv) +{ + const char *cmd; + struct passwd *pw; + uid_t uid; + uid_t target = 0; + gid_t groups[1]; + int ngroups; + int i, ch; + + setprogname("doas"); + + closefrom(STDERR_FILENO + 1); + + uid = getuid(); + if (uid != 0) + errc(1, EPERM, "root only"); + + while ((ch = getopt(argc, argv, "u:")) != -1) { + switch (ch) { + case 'u': + if (parseuid(optarg, &target) != 0) + errx(1, "unknown user"); + break; + default: + usage(); + break; + } + } + argv += optind; + argc -= optind; + + if (!argc) + usage(); + + cmd = argv[0]; + + pw = getpwuid(target); + if (!pw) + errx(1, "no passwd entry for target"); + groups[0] = pw->pw_gid; + + if (setgroups(1, groups) || + setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || + setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) + err(1, "failed to change user"); + + execvp(cmd, argv); + if (errno == ENOENT) + errx(1, "%s: command not found", cmd); + err(1, "%s", cmd); +} |