hi,
here's an updated diff using /var/doas directory root:wheel owned with a
strict 700 permissions. checks and batteries included.
Index: doas.c
===================================================================
RCS file: /cvs/src/usr.bin/doas/doas.c,v
retrieving revision 1.27
diff -u -p -u -p -r1.27 doas.c
--- doas.c 26 Jul 2015 22:44:33 -0000 1.27
+++ doas.c 27 Jul 2015 15:32:27 -0000
@@ -18,12 +18,14 @@
#include <sys/types.h>
#include <sys/stat.h>
+#include <fcntl.h>
#include <limits.h>
#include <login_cap.h>
#include <bsd_auth.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include <err.h>
#include <unistd.h>
#include <pwd.h>
@@ -52,6 +54,39 @@ arraylen(const char **arr)
return cnt;
}
+int
+checktimeout (const char *username)
+{
+ char path[PATH_MAX];
+ struct stat stinfo;
+ time_t tv;
+ int fh;
+
+ if (!stat("/var/doas", (struct stat *)&stinfo)) {
+ if(stinfo.st_mode != (S_IFDIR|S_IRWXU))
+ errx(1,"/var/doas must be a directory, owned by root:wheel,
and not writable nor readable by world or group");
+ if(stinfo.st_uid != 0 && stinfo.st_gid != 0)
+ errx(1,"/var/doas must belong to root:wheel");
+ } else {
+ perror ("doas");
+ exit(-1);
+ }
+
+ snprintf((char
*)&path,PATH_MAX-1,"/var/doas/doas.timestamp.%s",username);
+ tv = time((time_t *)NULL);
+
+ if (!stat(path,(struct stat *)&stinfo) &&
(tv-stinfo.st_mtim.tv_sec)<pw_timeout)
+ return 1;
+ else {
+ fh = creat(path,S_IRUSR|S_IWUSR);
+ close(fh);
+ return 0;
+ }
+ return 0;
+}
+
+
+
static int
parseuid(const char *s, uid_t *uid)
{
@@ -399,7 +434,7 @@ main(int argc, char **argv, char **envp)
"failed command for %s: %s", myname, cmdline);
fail();
}
-
+ if (pw_timeout && !checktimeout(pw->pw_name)) {
if (!(rule->options & NOPASS)) {
if (nflag)
errx(1, "Authorization required");
@@ -409,6 +444,7 @@ main(int argc, char **argv, char **envp)
fail();
}
}
+}
envp = copyenv((const char **)envp, rule);
pw = getpwuid(target);
Index: doas.conf.5
===================================================================
RCS file: /cvs/src/usr.bin/doas/doas.conf.5,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 doas.conf.5
--- doas.conf.5 23 Jul 2015 15:26:37 -0000 1.11
+++ doas.conf.5 27 Jul 2015 15:32:27 -0000
@@ -22,10 +22,21 @@
.Sh DESCRIPTION
The
.Xr doas 1
-utility executes commands as other users according to the rules
+utility executes commands as other users according to the rules and options
in the
.Nm
configuration file.
+.Sh OPTIONS
+.Pp
+The configuration file currently accepts one option:
+.Bd -ragged -offset indent
+.Ic timeout
+tsec
+.Pp
+By default
+.Ic doas
+prompts for password on every execution. This option sets timeout for
password reprompt to the tsec seconds value.
+.Sh RULES
.Pp
The rules have the following format:
.Bd -ragged -offset indent
@@ -113,6 +124,9 @@ and additionally permits tedu to run pro
.Bd -literal -offset indent
# Non-exhaustive list of variables needed to
# build release(8) and ports(7)
+# timeout is optional
+timeout 300 # sets the password reprompt time out to 5 minutes
+
permit nopass keepenv { \e
FTPMODE PKG_CACHE PKG_PATH SM_PATH SSH_AUTH_SOCK \e
DESTDIR DISTDIR FETCH_CMD FLAVOR GROUP MAKE MAKECONF \e
Index: doas.h
===================================================================
RCS file: /cvs/src/usr.bin/doas/doas.h,v
retrieving revision 1.4
diff -u -p -u -p -r1.4 doas.h
--- doas.h 24 Jul 2015 06:36:42 -0000 1.4
+++ doas.h 27 Jul 2015 15:32:27 -0000
@@ -10,6 +10,7 @@ struct rule {
const char **envlist;
};
+extern time_t pw_timeout;
extern struct rule **rules;
extern int nrules, maxrules;
extern int parse_errors;
Index: parse.y
===================================================================
RCS file: /cvs/src/usr.bin/doas/parse.y,v
retrieving revision 1.10
diff -u -p -u -p -r1.10 parse.y
--- parse.y 24 Jul 2015 06:36:42 -0000 1.10
+++ parse.y 27 Jul 2015 15:32:27 -0000
@@ -17,6 +17,7 @@
%{
#include <sys/types.h>
+#include <sys/limits.h>
#include <ctype.h>
#include <unistd.h>
#include <stdint.h>
@@ -24,6 +25,7 @@
#include <stdio.h>
#include <string.h>
#include <err.h>
+#include <errno.h>
#include "doas.h"
@@ -45,6 +47,7 @@ typedef struct {
FILE *yyfp;
+time_t pw_timeout;
struct rule **rules;
int nrules, maxrules;
int parse_errors = 0;
@@ -56,7 +59,7 @@ int yyparse(void);
%}
%token TPERMIT TDENY TAS TCMD TARGS
-%token TNOPASS TKEEPENV
+%token TNOPASS TKEEPENV TTIMEOUT
%token TSTRING
%%
@@ -64,9 +67,21 @@ int yyparse(void);
grammar: /* empty */
| grammar '\n'
| grammar rule '\n'
+ | grammar timeout '\n'
| error '\n'
;
+timeout: TTIMEOUT TSTRING {
+ errno = 0;
+ char *ep;
+ pw_timeout = strtol($2.str,&ep,10);
+ if ($2.str[0] == '\0' || *ep != '\0')
+ errx (1, "timeout must be a number of seconds");
+ if (errno == ERANGE && pw_timeout == ULONG_MAX)
+ errx (1, "timeout is out of range");
+ //printf ("Timeout is: %d\n",timeout);
+ };
+
rule: action ident target cmd {
struct rule *r;
r = calloc(1, sizeof(*r));
@@ -193,6 +208,7 @@ struct keyword {
{ "args", TARGS },
{ "nopass", TNOPASS },
{ "keepenv", TKEEPENV },
+ { "timeout", TTIMEOUT },
};
int