diff options
Diffstat (limited to 'harmony/busybox/bbsuid.c')
-rw-r--r-- | harmony/busybox/bbsuid.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/harmony/busybox/bbsuid.c b/harmony/busybox/bbsuid.c new file mode 100644 index 000000000..8be2671b1 --- /dev/null +++ b/harmony/busybox/bbsuid.c @@ -0,0 +1,106 @@ +/* + * 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/umount", + "/bin/su", + "/usr/bin/crontab", + "/usr/bin/passwd", + "/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; +} + |