=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/doas/doas.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- src/usr.bin/doas/doas.c 2015/07/20 01:04:37 1.14 +++ src/usr.bin/doas/doas.c 2015/07/21 11:04:06 1.15 @@ -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 * @@ -97,7 +97,7 @@ 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 @@ } 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 @@ 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();