Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 4531021

Browse files
committedJan 23, 2017
Merge, update from OpenBSD
1 parent a15e6ed commit 4531021

File tree

6 files changed

+275
-185
lines changed

6 files changed

+275
-185
lines changed
 

‎doas.1

+2-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ It may fail for one of the following reasons:
8888
.Bl -bullet -compact
8989
.It
9090
The config file
91-
.Pa /etc/doas.conf
91+
.Pa /usr/local/etc/doas.conf
9292
could not be parsed.
9393
.It
9494
The user attempted to run a command which is not permitted.
@@ -106,4 +106,4 @@ The
106106
command first appeared in
107107
.Ox 5.8 .
108108
.Sh AUTHORS
109-
.An Ted Unangst Aq Mt tedu@openbsd.org
109+
.An Ted Unangst Aq Mt tedu@openbsd.org

‎doas.c

+68-50
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <sys/types.h>
1919
#include <sys/stat.h>
20+
#include <sys/ioctl.h>
2021

2122
#if defined(HAVE_INTTYPES_H)
2223
#include <inttypes.h>
@@ -39,6 +40,7 @@
3940
#include <grp.h>
4041
#include <syslog.h>
4142
#include <errno.h>
43+
#include <fcntl.h>
4244

4345
#if defined(HAVE_LOGIN_CAP_H)
4446
#include <login_cap.h>
@@ -83,18 +85,6 @@ errc(int eval, int code, const char *format)
8385
}
8486
#endif
8587

86-
size_t
87-
arraylen(const char **arr)
88-
{
89-
size_t cnt = 0;
90-
91-
while (*arr) {
92-
cnt++;
93-
arr++;
94-
}
95-
return cnt;
96-
}
97-
9888
static int
9989
parseuid(const char *s, uid_t *uid)
10090
{
@@ -254,6 +244,54 @@ checkconfig(const char *confpath, int argc, char **argv,
254244
}
255245
}
256246

247+
#if defined(USE_BSD_AUTH)
248+
static void
249+
authuser(char *myname, char *login_style, int persist)
250+
{
251+
char *challenge = NULL, *response, rbuf[1024], cbuf[128];
252+
auth_session_t *as;
253+
int fd = -1;
254+
255+
if (persist)
256+
fd = open("/dev/tty", O_RDWR);
257+
if (fd != -1) {
258+
if (ioctl(fd, TIOCCHKVERAUTH) == 0)
259+
goto good;
260+
}
261+
262+
if (!(as = auth_userchallenge(myname, login_style, "auth-doas",
263+
&challenge)))
264+
errx(1, "Authorization failed");
265+
if (!challenge) {
266+
char host[HOST_NAME_MAX + 1];
267+
if (gethostname(host, sizeof(host)))
268+
snprintf(host, sizeof(host), "?");
269+
snprintf(cbuf, sizeof(cbuf),
270+
"\rdoas (%.32s@%.32s) password: ", myname, host);
271+
challenge = cbuf;
272+
}
273+
response = readpassphrase(challenge, rbuf, sizeof(rbuf),
274+
RPP_REQUIRE_TTY);
275+
if (response == NULL && errno == ENOTTY) {
276+
syslog(LOG_AUTHPRIV | LOG_NOTICE,
277+
"tty required for %s", myname);
278+
errx(1, "a tty is required");
279+
}
280+
if (!auth_userresponse(as, response, 0)) {
281+
syslog(LOG_AUTHPRIV | LOG_NOTICE,
282+
"failed auth for %s", myname);
283+
errc(1, EPERM, NULL);
284+
}
285+
explicit_bzero(rbuf, sizeof(rbuf));
286+
good:
287+
if (fd != -1) {
288+
int secs = 5 * 60;
289+
ioctl(fd, TIOCSETVERAUTH, &secs);
290+
close(fd);
291+
}
292+
}
293+
#endif
294+
257295
int
258296
main(int argc, char **argv)
259297
{
@@ -283,25 +321,27 @@ main(int argc, char **argv)
283321
setprogname("doas");
284322
#endif
285323

286-
/*
287-
if (pledge("stdio rpath getpw tty proc exec id", NULL) == -1)
288-
err(1, "pledge");
289-
*/
290-
291324
#ifndef linux
292325
closefrom(STDERR_FILENO + 1);
293326
#endif
294327

295328
uid = getuid();
296329

297330
while ((ch = getopt(argc, argv, "a:C:nsu:")) != -1) {
331+
/* while ((ch = getopt(argc, argv, "a:C:Lnsu:")) != -1) { */
298332
switch (ch) {
299333
case 'a':
300334
login_style = optarg;
301335
break;
302336
case 'C':
303337
confpath = optarg;
304338
break;
339+
/* case 'L':
340+
i = open("/dev/tty", O_RDWR);
341+
if (i != -1)
342+
ioctl(i, TIOCCLRVERAUTH);
343+
exit(i != -1);
344+
*/
305345
case 'u':
306346
if (parseuid(optarg, &target) != 0)
307347
errx(1, "unknown user");
@@ -343,9 +383,11 @@ main(int argc, char **argv)
343383

344384
if (sflag) {
345385
sh = getenv("SHELL");
346-
if (sh == NULL || *sh == '\0')
347-
shargv[0] = pw->pw_shell;
348-
else
386+
if (sh == NULL || *sh == '\0') {
387+
shargv[0] = strdup(pw->pw_shell);
388+
if (shargv[0] == NULL)
389+
err(1, NULL);
390+
} else
349391
shargv[0] = sh;
350392
argv = shargv;
351393
argc = 1;
@@ -357,11 +399,14 @@ main(int argc, char **argv)
357399
exit(1); /* fail safe */
358400
}
359401

402+
if (geteuid())
403+
errx(1, "not installed setuid");
404+
360405
parseconfig(DOAS_CONF, 1);
361406

362407
/* cmdline is used only for logging, no need to abort on truncate */
363408
#ifndef linux
364-
(void) strlcpy(cmdline, argv[0], sizeof(cmdline));
409+
(void)strlcpy(cmdline, argv[0], sizeof(cmdline));
365410
for (i = 1; i < argc; i++) {
366411
if (strlcat(cmdline, " ", sizeof(cmdline)) >= sizeof(cmdline))
367412
break;
@@ -379,44 +424,18 @@ main(int argc, char **argv)
379424

380425
cmd = argv[0];
381426
if (!permit(uid, groups, ngroups, &rule, target, cmd,
382-
(const char**)argv + 1)) {
427+
(const char **)argv + 1)) {
383428
syslog(LOG_AUTHPRIV | LOG_NOTICE,
384429
"failed command for %s: %s", myname, cmdline);
385430
errc(1, EPERM, NULL);
386431
}
387432

388433
if (!(rule->options & NOPASS)) {
389434
#if defined(USE_BSD_AUTH)
390-
char *challenge = NULL, *response, rbuf[1024], cbuf[128];
391-
auth_session_t *as;
392-
393435
if (nflag)
394436
errx(1, "Authorization required");
395437

396-
if (!(as = auth_userchallenge(myname, login_style, "auth-doas",
397-
&challenge)))
398-
errx(1, "Authorization failed");
399-
if (!challenge) {
400-
char host[MAXHOSTNAME + 1];
401-
if (gethostname(host, sizeof(host)))
402-
snprintf(host, sizeof(host), "?");
403-
snprintf(cbuf, sizeof(cbuf),
404-
"\rdoas (%.32s@%.32s) password: ", myname, host);
405-
challenge = cbuf;
406-
}
407-
response = readpassphrase(challenge, rbuf, sizeof(rbuf),
408-
RPP_REQUIRE_TTY);
409-
if (response == NULL && errno == ENOTTY) {
410-
syslog(LOG_AUTHPRIV | LOG_NOTICE,
411-
"tty required for %s", myname);
412-
errx(1, "a tty is required");
413-
}
414-
if (!auth_userresponse(as, response, 0)) {
415-
syslog(LOG_AUTHPRIV | LOG_NOTICE,
416-
"failed auth for %s", myname);
417-
errc(1, EPERM, NULL);
418-
}
419-
explicit_bzero(rbuf, sizeof(rbuf));
438+
authuser(myname, login_style, rule->options & PERSIST);
420439
#elif defined(USE_PAM)
421440
#define PAM_END(msg) do { \
422441
syslog(LOG_ERR, "%s: %s", msg, pam_strerror(pamh, pam_err)); \
@@ -518,7 +537,6 @@ main(int argc, char **argv)
518537
#else
519538
#error No auth module!
520539
#endif
521-
522540
}
523541

524542
/*

‎doas.conf.5

+26-12
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.\" $OpenBSD: doas.conf.5,v 1.26 2016/06/11 17:17:10 tedu Exp $
1+
.\" $OpenBSD: doas.conf.5,v 1.31 2016/12/05 10:58:07 schwarze Exp $
22
.\"
33
.\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
44
.\"
@@ -13,7 +13,7 @@
1313
.\"WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1414
.\"ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1515
.\"OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16-
.Dd $Mdocdate: June 11 2016 $
16+
.Dd $Mdocdate: December 5 2016 $
1717
.Dt DOAS.CONF 5
1818
.Os
1919
.Sh NAME
@@ -35,7 +35,7 @@ The rules have the following format:
3535
.Op Ar options
3636
.Ar identity
3737
.Op Ic as Ar target
38-
.Op Ic cmd Ar command Op Ic args ...
38+
.Op Ic cmd Ar command Op Ic args No ...
3939
.Ed
4040
.Pp
4141
Rules consist of the following parts:
@@ -47,6 +47,9 @@ Options are:
4747
.Bl -tag -width keepenv
4848
.It Ic nopass
4949
The user is not required to enter a password.
50+
.It Ic persist
51+
After the user successfully authenticates, do not ask for a password
52+
again for some time.
5053
.It Ic keepenv
5154
The user's environment is maintained.
5255
The default is to reset the environment, except for the variables
@@ -59,9 +62,18 @@ The default is to reset the environment, except for the variables
5962
.Ev USER
6063
and
6164
.Ev USERNAME .
62-
.It Ic keepenv { Oo Ar variable ... Oc Ic }
65+
.It Ic setenv { Oo Ar variable ... Oc Oo Ar variable=value ... Oc Ic }
6366
In addition to the variables mentioned above, keep the space-separated
6467
specified variables.
68+
Variables may also be removed with a leading
69+
.Sq -
70+
or set using the latter syntax.
71+
If the first character of
72+
.Ar value
73+
is a
74+
.Ql $
75+
then the value to be set is taken from the existing environment
76+
variable of the same name.
6577
.El
6678
.It Ar identity
6779
The username to match.
@@ -78,7 +90,7 @@ Be advised that it is best to specify absolute paths.
7890
If a relative path is specified, only a restricted
7991
.Ev PATH
8092
will be searched.
81-
.It Ic args ...
93+
.It Ic args Op Ar argument ...
8294
Arguments to command.
8395
The command arguments provided by the user need to match those specified.
8496
The keyword
@@ -109,25 +121,27 @@ If quotes or backslashes are used in a word,
109121
it is not considered a keyword.
110122
.El
111123
.Sh EXAMPLES
112-
The following example permits users in group wsrc to build ports,
124+
The following example permits users in group wsrc to build ports;
113125
wheel to execute commands as any user while keeping the environment
114126
variables
115-
.Ev ENV ,
116-
.Ev PS1 ,
127+
.Ev PS1
117128
and
118-
.Ev SSH_AUTH_SOCK ,
119-
permits tedu to run procmap as root without a password,
129+
.Ev SSH_AUTH_SOCK
130+
and
131+
unsetting
132+
.Ev ENV ;
133+
permits tedu to run procmap as root without a password;
120134
and additionally permits root to run unrestricted commands as itself.
121135
.Bd -literal -offset indent
122136
# Non-exhaustive list of variables needed to
123137
# build release(8) and ports(7)
124-
permit nopass keepenv { \e
138+
permit nopass setenv { \e
125139
FTPMODE PKG_CACHE PKG_PATH SM_PATH SSH_AUTH_SOCK \e
126140
DESTDIR DISTDIR FETCH_CMD FLAVOR GROUP MAKE MAKECONF \e
127141
MULTI_PACKAGES NOMAN OKAY_FILES OWNER PKG_DBDIR \e
128142
PKG_DESTDIR PKG_TMPDIR PORTSDIR RELEASEDIR SHARED_ONLY \e
129143
SUBPACKAGE WRKOBJDIR SUDO_PORT_V1 } :wsrc
130-
permit nopass keepenv { ENV PS1 SSH_AUTH_SOCK } :wheel
144+
permit setenv { -ENV PS1=$DOAS_PS1 SSH_AUTH_SOCK } :wheel
131145
permit nopass tedu as root cmd /usr/sbin/procmap
132146
permit nopass keepenv root as root
133147
.Ed

‎doas.h

+19-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,20 @@
1-
/* $OpenBSD: doas.h,v 1.8 2016/06/19 19:29:43 martijn Exp $ */
1+
/* $OpenBSD: doas.h,v 1.12 2016/10/05 17:40:25 tedu Exp $ */
2+
/*
3+
* Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
4+
*
5+
* Permission to use, copy, modify, and distribute this software for any
6+
* purpose with or without fee is hereby granted, provided that the above
7+
* copyright notice and this permission notice appear in all copies.
8+
*
9+
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10+
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11+
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12+
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13+
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14+
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15+
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16+
*/
17+
218
struct rule {
319
int action;
420
int options;
@@ -10,18 +26,17 @@ struct rule {
1026
};
1127

1228
extern struct rule **rules;
13-
extern int nrules, maxrules;
29+
extern int nrules;
1430
extern int parse_errors;
1531

16-
size_t arraylen(const char **);
17-
1832
char **prepenv(struct rule *);
1933

2034
#define PERMIT 1
2135
#define DENY 2
2236

2337
#define NOPASS 0x1
2438
#define KEEPENV 0x2
39+
#define PERSIST 0x4
2540

2641
#ifndef UID_MAX
2742
#define UID_MAX 65535
There was a problem loading the remainder of the diff.

0 commit comments

Comments
 (0)
Please sign in to comment.