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

Reply via email to