aboutsummaryrefslogtreecommitdiffstats
path: root/main/busybox/bbsuid.c
blob: f015163e0e74dd7788f11d545bede7994782e7b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 * Copyright (C) 2008 Natanael Copa <natanael.copa@gmail.com>
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation. See http://www.gnu.org/ for details.
 *
 */

#include <sys/stat.h>
#include <sys/types.h>

#include <libgen.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#define BBSUID_PATH "/bin/bbsuid"

const static char * applets[] = {
	"/bin/mount",
	"/bin/ping",
	"/bin/ping6",
	"/bin/umount",
	"/usr/bin/crontab",
	"/usr/bin/passwd",
	"/usr/bin/su",
	"/usr/bin/traceroute",
	"/usr/bin/traceroute6",
	"/usr/bin/vlock",
	NULL
};


static const char *applet_from_path(const char *str)
{
	const char *p = strrchr(str, '/');
	if (p == NULL)
		p = str;
	else
		p++;
	return p;
}

static int is_valid_applet(const char *str)
{
	int i;
	for (i = 0; applets[i] != NULL; i++) {
		const char *a = applet_from_path(applets[i]);
		if (strcmp(applet_from_path(str), a) == 0)
			return 1;
	}
	return 0;
}

int exec_busybox(const char *app, int argc, char **argv)
{
	char **newargv = malloc((argc + 2) * sizeof(char *));
	int i;
	newargv[0] = "/bin/busybox";
	newargv[1] = (char *)app;
	for (i = 1; i < argc; i++)
		newargv[i+1] = argv[i];
	newargv[argc+1] = NULL;
	execv(newargv[0], newargv);
	perror(newargv[0]);
	free(newargv);
	return 1;
}

static int install_links(void)
{
	int i, r = 0;
	/* we don't want others than root to install the symlinks */
	if (getuid() != 0)
		errx(1, "Only root can install symlinks");

	for (i = 0; applets[i] != NULL; i++) {
		const char *a = applets[i];
		struct stat st;
		if (lstat(a, &st) == 0 && S_ISLNK(st.st_mode))
			unlink(a);
		if (symlink(BBSUID_PATH, a) < 0)
			r++;
	}

	return r;
}

int main(int argc, char **argv)
{
	const char *app = applet_from_path(argv[0]);
	
	if (strcmp(app, "bbsuid") == 0) {
		if (argc == 2 && strcmp(argv[1], "--install") == 0)
			return install_links();
		errx(1, "Use --install to install symlinks");
	}

	if (is_valid_applet(app))
		return exec_busybox(app, argc, argv);
	
	errx(1, "%s is not a valid applet", app);
	return 1;
}