Git-Url: http://git.frugalware.org/gitweb/gitweb.cgi?p=frugalware-current.git;a=commitdiff;h=67c0c3e137cba99ba2290cdd46bd2f460a3ae346
commit 67c0c3e137cba99ba2290cdd46bd2f460a3ae346 Author: James Buren <r...@frugalware.org> Date: Thu May 19 17:25:54 2011 -0500 fw32-0.2-1-x86_64 * rewrite fw32-run in C to bypass need for sudo (using SETUID instead) diff --git a/source/apps-extra/fw32/FrugalBuild b/source/apps-extra/fw32/FrugalBuild index fc1697c..3198237 100644 --- a/source/apps-extra/fw32/FrugalBuild +++ b/source/apps-extra/fw32/FrugalBuild @@ -2,7 +2,7 @@ # Maintainer: James Buren <r...@frugalware.org> pkgname=fw32 -pkgver=0.1 +pkgver=0.2 pkgrel=1 pkgdesc="A framework for maintaining an i686 environment on x86_64." url="http://www.frugalware.org" @@ -11,15 +11,21 @@ groups=('apps-extra') archs=('!i686' 'x86_64' '!ppc' '!arm') up2date="$pkgver" backup=('etc/fw32/pacman-g2.conf') -source=(fw32 pacman-g2.conf) -sha1sums=('93dbc5084fe9e86459eec01713d4817fcf0f13a5' \ - 'd84ca5b6d1c37993dd6514d41eb4923a057a0d27') +source=(fw32 pacman-g2.conf fw32-run.c) +sha1sums=('17a8e653ec4292975f226851c2296680096ddc9f' \ + 'd84ca5b6d1c37993dd6514d41eb4923a057a0d27' \ + '83e685227ac174e37f1d71d04d0540cc2fac9236') build() { Fexe /usr/bin/fw32 - for i in fw32-{create,update,install,uninstall,clean,delete,mount,umount,run}; do - Fln /usr/bin/fw32 /usr/bin/$i + for i in fw32-{create,update,install,uninstall,clean,delete,mount,umount}; do + Fln fw32 /usr/bin/$i done Ffile /etc/fw32/pacman-g2.conf + Fexec cc -Wall -Wextra $CFLAGS fw32-run.c -o fw32-run + Fexe /usr/bin/fw32-run + Fexec chmod u+s $Fdestdir/usr/bin/fw32-run } + +# optimization OK diff --git a/source/apps-extra/fw32/fw32 b/source/apps-extra/fw32/fw32 index 8188f1e..4acd213 100644 --- a/source/apps-extra/fw32/fw32 +++ b/source/apps-extra/fw32/fw32 @@ -101,19 +101,6 @@ case $0 in [ $? -ne 0 ] && error "Failed to umount fw32 root directories." done ;; - *fw32-run) - [ $UID -eq 0 ] && error "This must be run as non-root." - [ ! -d $FW32_ROOT ] && error "fw32 root directory does not exist." - grep -q -E "$FW32_ROOT/(tmp|proc|sys|dev)" /proc/mounts - [ $? -ne 0 ] && error "fw32 root directories are not mounted." - mount_home - TMP="$@" - if [ ${#TMP} -eq 0 ]; then - sudo linux32 /usr/sbin/chroot $FW32_ROOT su -l $USER - else - sudo linux32 /usr/sbin/chroot $FW32_ROOT su -l -c "${TMP[@]}" $USER - fi - ;; esac exit 0 diff --git a/source/apps-extra/fw32/fw32-run.c b/source/apps-extra/fw32/fw32-run.c new file mode 100644 index 0000000..4951945 --- /dev/null +++ b/source/apps-extra/fw32/fw32-run.c @@ -0,0 +1,203 @@ +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <limits.h> +#include <errno.h> +#include <unistd.h> +#include <pwd.h> +#include <sys/stat.h> +#include <sys/mount.h> +#include <sys/personality.h> + +#define FW32_ROOT "/usr/lib/fw32" + +static void error(const char *msg) __attribute__ ((noreturn)); +static void check_mounts(void); +static int check_home_directory(const char *dst); +static void make_home_directory(char *dst); +static void mount_home(const char *src); +extern int main(int argc,char **argv); + +static void +error(const char *msg) +{ + fputs(msg,stderr); + + exit(EXIT_FAILURE); +} + +static void +check_mounts(void) +{ + FILE *file; + char line[LINE_MAX], *s, *e; + int tmp, proc, sys, dev; + + file = fopen("/proc/mounts","r"); + + if(!file) + error("Failed to open /proc/mounts.\n"); + + tmp = proc = sys = dev = 0; + + while(fgets(line,sizeof line,file)) + { + s = strchr(line,' '); + if(!s) + continue; + e = strchr(++s,' '); + if(!e) + continue; + *e = 0; + if(!strcmp(s,FW32_ROOT "/tmp")) + tmp = 1; + else if(!strcmp(s,FW32_ROOT "/proc")) + proc = 1; + else if(!strcmp(s,FW32_ROOT "/sys")) + sys = 1; + else if(!strcmp(s,FW32_ROOT "/dev")) + dev = 1; + } + + if(!tmp || !proc || !sys || !dev) + { + fclose(file); + error("fw32 root directories are not mounted.\n"); + } + + fclose(file); +} + +static int +check_home_directory(const char *dst) +{ + FILE *file; + char line[LINE_MAX], *s, *e; + int found; + + file = fopen("/proc/mounts","r"); + + if(!file) + error("Failed to open /proc/mounts.\n"); + + found = 0; + + while(fgets(line,sizeof line,file)) + { + s = strchr(line,' '); + if(!s) + continue; + e = strchr(++s,' '); + if(!e) + continue; + *e = 0; + if(!strcmp(s,dst)) + { + found = 1; + break; + } + } + + fclose(file); + + return found; +} + +static void +make_home_directory(char *dst) +{ + char *p; + + p = dst + 1; + + errno = 0; + + while(1) + { + p = strchr(p,'/'); + + if(!p) + break; + + *p = 0; + + mkdir(dst,0755); + + switch(errno) + { + case EEXIST: + errno = 0; + break; + case 0: + break; + default: + error("Failed to create home directory.\n"); + } + + *p = '/'; + + ++p; + } + + errno = 0; + + mkdir(dst,0755); + + if(errno != 0 && errno != EEXIST) + error("Failed to create home directory.\n"); +} + + +static void +mount_home(const char *src) +{ + char dst[PATH_MAX]; + + snprintf(dst,sizeof dst,"%s%s",FW32_ROOT,src); + + if(check_home_directory(dst)) + return; + + make_home_directory(dst); + + if(mount(src,dst,"",MS_BIND,"")) + error("Failed to mount home directory.\n"); +} + +extern int +main(int argc,char **argv) +{ + struct stat st; + struct passwd *pwd; + + if(!getuid() || geteuid()) + error("This must be run as non-root, be SETUID, and owned by root.\n"); + + if(stat(FW32_ROOT,&st)) + error("fw32 root directory does not exist.\n"); + + check_mounts(); + + pwd = getpwuid(getuid()); + + if(!pwd) + error("Failed to retrieve password entry.\n"); + + mount_home(pwd->pw_dir); + + if(personality(PER_LINUX32)) + error("Failed to enable 32 bit emulation.\n"); + + if(chroot(FW32_ROOT)) + error("Failed to enter chroot.\n"); + + if(setuid(getuid())) + error("Failed to drop root permissions.\n"); + + if(argc < 2) + execl(pwd->pw_shell,pwd->pw_shell,(char *) 0); + else + execvp(argv[1],argv+1); + + return EXIT_SUCCESS; +} _______________________________________________ Frugalware-git mailing list Frugalware-git@frugalware.org http://frugalware.org/mailman/listinfo/frugalware-git