]> git.armaanb.net Git - opendoas.git/commitdiff
Add argument matching support to doas.
authorVadim Zhukov <zhuk@openbsd.org>
Tue, 21 Jul 2015 11:04:06 +0000 (11:04 +0000)
committerVadim Zhukov <zhuk@openbsd.org>
Tue, 21 Jul 2015 11:04:06 +0000 (11:04 +0000)
Input and generic support from many. Final okay from tedu@.

doas.1
doas.c
doas.conf.5
doas.h
parse.y

diff --git a/doas.1 b/doas.1
index cd076ea0205ce31d03e12a15264c2938f0990843..351d5fd82462f333ab4fc6930a26bb8fbfaf1d6e 100644 (file)
--- a/doas.1
+++ b/doas.1
@@ -1,4 +1,4 @@
-.\" $OpenBSD: doas.1,v 1.6 2015/07/19 16:42:31 espie Exp $
+.\" $OpenBSD: doas.1,v 1.7 2015/07/19 17:00:22 jmc Exp $
 .\"
 .\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
 .\"
@@ -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/doas.c b/doas.c
index a712bc3799970a2f6096d82ac16ed9ef1c3fd1ec..b77e17f6953eb88faa8bd69f95f5ac8fc7a3f35d 100644 (file)
--- a/doas.c
+++ b/doas.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: doas.c,v 1.13 2015/07/20 01:00:48 tedu Exp $ */
+/* $OpenBSD: doas.c,v 1.14 2015/07/20 01:04:37 tedu 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();
index 8d3cd1eb109f0e48c9cf1197016b6c14c4429bfa..7510bd0b4ac0219f36d7e766307e9b9a29b337ea 100644 (file)
@@ -1,4 +1,4 @@
-.\" $OpenBSD: doas.conf.5,v 1.6 2015/07/20 07:43:27 jmc Exp $
+.\" $OpenBSD: doas.conf.5,v 1.7 2015/07/20 20:18:45 tedu Exp $
 .\"
 .\"Copyright (c) 2015 Ted Unangst <tedu@openbsd.org>
 .\"
@@ -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/doas.h b/doas.h
index 8576e41668787a6faa3fac5fd7614663cd7f385a..9f0e5e491a43165e091222cdd3ab76edaade9e0e 100644 (file)
--- a/doas.h
+++ b/doas.h
@@ -1,4 +1,4 @@
-/* $OpenBSD$ */
+/* $OpenBSD: doas.h,v 1.2 2015/07/18 07:49:16 bcallah 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/parse.y b/parse.y
index f1e90ab9039fc555fd05e4a0acf6890d922888fd..7dc18161183081a8091067f927f3b37baf66ec83 100644 (file)
--- a/parse.y
+++ b/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.5 2015/07/19 22:09:08 benno Exp $ */
+/* $OpenBSD: parse.y,v 1.6 2015/07/19 22:11:41 benno 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 },
 };