commit 836d0723d883384c1ea8e1b4c3fd23eced9c8043
parent 8078fe60673809c9ce32dd85613e9f96d7278742
Author: pancake <unknown>
Date: Thu, 31 Mar 2011 20:56:00 +0200
* Find binaries in PATH when specified in path '*'
* Check return value of lstat
Diffstat:
2 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/config.def.h b/config.def.h
@@ -14,6 +14,7 @@ static struct rule_t rules[] = {
{ USER, GROUP, "ifconfig", "/sbin/ifconfig" },
{ USER, GROUP, "ls", "/bin/ls" },
{ USER, GROUP, "wifi", "/root/wifi.sh" },
- { USER, GROUP, "", ""}, // allow to run any program
+ { USER, GROUP, "cp", "*"}, // allow to run this program in PATH
+ { USER, GROUP, "*", "*"}, // allow to run any program in PATH
{ 0 },
};
diff --git a/sup.c b/sup.c
@@ -1,13 +1,14 @@
-/* pancake <nopcode.org> -- Copyleft 2009 */
+/* pancake <nopcode.org> -- Copyleft 2009-2011 */
#include <errno.h>
-#include <stdio.h>
#include <unistd.h>
+#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include <sys/stat.h>
#define HELP "sup [-hlv] [cmd ..]"
-#define VERSION "sup 0.1 pancake <nopcode.org> copyleft 2009"
+#define VERSION "sup 0.1 pancake <nopcode.org> copyleft 2011"
struct rule_t {
int uid;
@@ -19,11 +20,30 @@ struct rule_t {
#include "config.h"
static int die(int ret, const char *org, const char *str) {
- fprintf (stderr, "%s%s%s\n", org, org?": ":"", str);
+ fprintf (stderr, "%s%s%s\n", org?org:"", org?": ":"", str);
return ret;
}
+static char *getpath(const char *str) {
+ struct stat st;
+ static char file[4096];
+ char *p, *path = getenv ("PATH");
+ if (path)
+ for (p = path; *p; p++) {
+ if (*p==':' && (p>path&&*(p-1)!='\\')) {
+ *p = 0;
+ snprintf (file, sizeof (file)-1, "%s/%s", path, str);
+ if (!lstat (file, &st))
+ return file;
+ *p = ':';
+ path = p+1;
+ }
+ }
+ return NULL;
+}
+
int main(int argc, char **argv) {
+ const char *cmd;
int i, uid, gid, ret;
if (argc < 2 || !strcmp (argv[1], "-h"))
@@ -43,18 +63,25 @@ int main(int argc, char **argv) {
gid = getgid ();
for (i = 0; rules[i].cmd != NULL; i++) {
- if (!rules[i].cmd[0] || !strcmp (argv[1], rules[i].cmd)) {
+ if (*rules[i].cmd=='*' || !strcmp (argv[1], rules[i].cmd)) {
#if ENFORCE
struct stat st;
- lstat (rules[i].path, &st);
+ if (*rules[i].path=='*') {
+ if (*argv[1]=='.' || *argv[1]=='/')
+ cmd = argv[1];
+ else if (!(cmd = getpath (argv[1])))
+ return die (1, "execv", "cannot find program");
+ } else cmd = rules[i].path;
+ if (lstat (cmd, &st) == -1)
+ return die (1, "lstat", "cannot stat program");
if (st.st_mode & 0222)
- return die (1, "stat", "Cannot run writable binaries.");
+ return die (1, "stat", "cannot run writable binaries.");
#endif
if (uid != SETUID && rules[i].uid != -1 && rules[i].uid != uid)
- return die (1, "urule", "User does not match");
+ return die (1, "urule", "user does not match");
if (gid != SETGID && rules[i].gid != -1 && rules[i].gid != gid)
- return die (1, "grule", "Group id does not match");
+ return die (1, "grule", "group id does not match");
if (setuid (SETUID) == -1 || setgid (SETGID) == -1 ||
seteuid (SETUID) == -1 || setegid (SETGID) == -1)
@@ -67,7 +94,7 @@ int main(int argc, char **argv) {
if (chdir (CHRDIR) == -1)
return die (1, "chdir", strerror (errno));
#endif
- ret = execv (*rules[i].path? rules[i].path:argv[1], argv+1);
+ ret = execv (cmd, argv+1);
return die (ret, "execv", strerror (errno));
}
}