diff options
author | Vadim Zhukov <zhuk@cvs.openbsd.org> | 2015-07-21 11:04:07 +0000 |
---|---|---|
committer | Vadim Zhukov <zhuk@cvs.openbsd.org> | 2015-07-21 11:04:07 +0000 |
commit | 675a9cf91844b4d1e750b78dfe0c5860d682b938 (patch) | |
tree | e0e35b70133dc4b72f1ef38ccacd0d2f9cf3db24 /usr.bin/doas | |
parent | 178a9afaa1ffc1e681bbefaf4776ea578e60cd9b (diff) |
Add argument matching support to doas.
Input and generic support from many. Final okay from tedu@.
Diffstat (limited to 'usr.bin/doas')
-rw-r--r-- | usr.bin/doas/doas.1 | 6 | ||||
-rw-r--r-- | usr.bin/doas/doas.c | 28 | ||||
-rw-r--r-- | usr.bin/doas/doas.conf.5 | 16 | ||||
-rw-r--r-- | usr.bin/doas/doas.h | 3 | ||||
-rw-r--r-- | usr.bin/doas/parse.y | 35 |
5 files changed, 69 insertions, 19 deletions
diff --git a/usr.bin/doas/doas.1 b/usr.bin/doas/doas.1 index e9c0cf401a4..7c0b4dec646 100644 --- a/usr.bin/doas/doas.1 +++ b/usr.bin/doas/doas.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: doas.1,v 1.7 2015/07/19 17:00:22 jmc Exp $ +.\" $OpenBSD: doas.1,v 1.8 2015/07/21 11:04:06 zhuk Exp $ .\" .\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> .\" @@ -13,7 +13,7 @@ .\"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. -.Dd $Mdocdate: July 19 2015 $ +.Dd $Mdocdate: July 21 2015 $ .Dt DOAS 1 .Os .Sh NAME @@ -55,6 +55,8 @@ could not be parsed. The user attempted to run a command which is not permitted. .It The password was incorrect. +.It +The actual program is absent or not executable. .El .Sh SEE ALSO .Xr doas.conf 5 diff --git a/usr.bin/doas/doas.c b/usr.bin/doas/doas.c index 8a562f3eb24..b89788532b2 100644 --- a/usr.bin/doas/doas.c +++ b/usr.bin/doas/doas.c @@ -1,4 +1,4 @@ -/* $OpenBSD: doas.c,v 1.14 2015/07/20 01:04:37 tedu Exp $ */ +/* $OpenBSD: doas.c,v 1.15 2015/07/21 11:04:06 zhuk Exp $ */ /* * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> * @@ -97,7 +97,7 @@ strtogid(const char *s) static int match(uid_t uid, gid_t *groups, int ngroups, uid_t target, const char *cmd, - struct rule *r) + const char **cmdargs, struct rule *r) { int i; @@ -117,20 +117,33 @@ match(uid_t uid, gid_t *groups, int ngroups, uid_t target, const char *cmd, } if (r->target && uidcheck(r->target, target) != 0) return 0; - if (r->cmd && strcmp(r->cmd, cmd) != 0) - return 0; + if (r->cmd) { + if (strcmp(r->cmd, cmd)) + return 0; + if (r->cmdargs) { + /* if arguments were given, they should match explicitly */ + for (i = 0; r->cmdargs[i]; i++) { + if (!cmdargs[i]) + return 0; + if (strcmp(r->cmdargs[i], cmdargs[i])) + return 0; + } + if (cmdargs[i]) + return 0; + } + } return 1; } static int permit(uid_t uid, gid_t *groups, int ngroups, struct rule **lastr, - uid_t target, const char *cmd) + uid_t target, const char *cmd, const char **cmdargs) { int i; *lastr = NULL; for (i = 0; i < nrules; i++) { - if (match(uid, groups, ngroups, target, cmd, rules[i])) + if (match(uid, groups, ngroups, target, cmd, cmdargs, rules[i])) *lastr = rules[i]; } if (!*lastr) @@ -334,7 +347,8 @@ main(int argc, char **argv, char **envp) errx(1, "command line too long"); } - if (!permit(uid, groups, ngroups, &rule, target, cmd)) { + if (!permit(uid, groups, ngroups, &rule, target, cmd, + (const char**)argv + 1)) { syslog(LOG_AUTHPRIV | LOG_NOTICE, "failed command for %s: %s", myname, cmdline); fail(); diff --git a/usr.bin/doas/doas.conf.5 b/usr.bin/doas/doas.conf.5 index 055c696c164..67da1f0e47f 100644 --- a/usr.bin/doas/doas.conf.5 +++ b/usr.bin/doas/doas.conf.5 @@ -1,4 +1,4 @@ -.\" $OpenBSD: doas.conf.5,v 1.7 2015/07/20 20:18:45 tedu Exp $ +.\" $OpenBSD: doas.conf.5,v 1.8 2015/07/21 11:04:06 zhuk Exp $ .\" .\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> .\" @@ -13,7 +13,7 @@ .\"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. -.Dd $Mdocdate: July 20 2015 $ +.Dd $Mdocdate: July 21 2015 $ .Dt DOAS.CONF 5 .Os .Sh NAME @@ -33,7 +33,9 @@ The rules have the following format: .Op Ar options .Ar identity .Op Ic as Ar target -.Op Ic cmd Ar command +.Oo +.Ic cmd Ar command Op Ic args ... +.Oc .Ed .Pp Rules consist of the following parts: @@ -71,6 +73,14 @@ The default is root. The command the user is allowed or denied to run. The default is all commands. Be advised that it's best to specify absolute paths. +.It Ic args Op ... +Arguments to command. +If specified, the command arguments set provided by user and +the command arguments set in rule should be the same for successful +rule match. +Specifying +.Ic args +alone means that command should be run without any arguments. .El .Pp The last matching rule determines the action taken. diff --git a/usr.bin/doas/doas.h b/usr.bin/doas/doas.h index 5385b0df594..5eef18e80c6 100644 --- a/usr.bin/doas/doas.h +++ b/usr.bin/doas/doas.h @@ -1,4 +1,4 @@ -/* $OpenBSD: doas.h,v 1.2 2015/07/18 07:49:16 bcallah Exp $ */ +/* $OpenBSD: doas.h,v 1.3 2015/07/21 11:04:06 zhuk Exp $ */ struct rule { int action; @@ -6,6 +6,7 @@ struct rule { const char *ident; const char *target; const char *cmd; + const char **cmdargs; const char **envlist; }; diff --git a/usr.bin/doas/parse.y b/usr.bin/doas/parse.y index 9c463cf1256..2e7bf0f9545 100644 --- a/usr.bin/doas/parse.y +++ b/usr.bin/doas/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.6 2015/07/19 22:11:41 benno Exp $ */ +/* $OpenBSD: parse.y,v 1.7 2015/07/21 11:04:06 zhuk Exp $ */ /* * Copyright (c) 2015 Ted Unangst <tedu@openbsd.org> * @@ -32,6 +32,8 @@ typedef struct { struct { int action; int options; + const char *cmd; + const char **cmdargs; const char **envlist; }; const char *str; @@ -50,7 +52,7 @@ int yyparse(void); %} -%token TPERMIT TDENY TAS TCMD +%token TPERMIT TDENY TAS TCMD TARGS %token TNOPASS TKEEPENV %token TSTRING @@ -71,7 +73,8 @@ rule: action ident target cmd { r->envlist = $1.envlist; r->ident = $2.str; r->target = $3.str; - r->cmd = $4.str; + r->cmd = $4.cmd; + r->cmdargs = $4.cmdargs; if (nrules == maxrules) { if (maxrules == 0) maxrules = 63; @@ -136,9 +139,28 @@ target: /* optional */ { } ; cmd: /* optional */ { - $$.str = NULL; - } | TCMD TSTRING { - $$.str = $2.str; + $$.cmd = NULL; + $$.cmdargs = NULL; + } | TCMD TSTRING args { + $$.cmd = $2.str; + $$.cmdargs = $3.cmdargs; + } ; + +args: /* empty */ { + $$.cmdargs = NULL; + } | TARGS argslist { + $$.cmdargs = $2.cmdargs; + } ; + +argslist: /* empty */ { + if (!($$.cmdargs = calloc(1, sizeof(char *)))) + errx(1, "can't allocate args"); + } | argslist TSTRING { + int nargs = arraylen($1.cmdargs); + if (!($$.cmdargs = reallocarray($1.cmdargs, nargs + 2, sizeof(char *)))) + errx(1, "can't allocate args"); + $$.cmdargs[nargs] = $2.str; + $$.cmdargs[nargs + 1] = NULL; } ; %% @@ -160,6 +182,7 @@ struct keyword { { "permit", TPERMIT }, { "as", TAS }, { "cmd", TCMD }, + { "args", TARGS }, { "nopass", TNOPASS }, { "keepenv", TKEEPENV }, }; |