On Fri, 2005-03-04 at 20:49 +0100, Han-Wen Nienhuys wrote:

> 
> Style nitpicks:[...]

This new version should make everybody happy.

Do you think this stuff can make it to 2.6?
-- 
Ciao,

                                        seba
--- lilypond-2.4.4/lily/main.cc 2004-11-04 17:46:43.000000000 +0100
+++ lilypond-2.4.4-patched/lily/main.cc 2005-03-05 00:07:32.931892411 +0100
@@ -11,6 +11,11 @@
 #include <assert.h>
 #include <locale.h>
 #include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/types.h>
 
 #include "config.hh"
 
@@ -115,6 +120,9 @@
    LOCAL_LILYPOND_DATADIR = /usr/share/lilypond/<VERSION> */
 char const *prefix_directory[] = {LILYPOND_DATADIR, LOCAL_LILYPOND_DATADIR, 0};
 
+/* The jail specification: USER,GROUP,JAIL,DIR. */
+static const char *jail_spec;
+
 /*  The option parser */
 static Getopt_long *option_parser = 0;
 
@@ -133,6 +141,7 @@
     {_i ("FIELD"), "header", 'H',  _i ("write header field to 
BASENAME.FIELD")},
     {_i ("DIR"), "include", 'I',  _i ("add DIR to search path")},
     {_i ("FILE"), "init", 'i',  _i ("use FILE as init file")},
+    {_i ("USER,GROUP,JAIL,DIR"), "jail", 'j', _i ("chroot to JAIL, become 
USER:GROUP and cd into DIR")},
     {0, "no-layout", 'm',  _i ("produce MIDI output only")},
     {_i ("FILE"), "output", 'o',  _i ("write output to FILE")},
     {0, "preview", 'p',  _i ("generate a preview")},
@@ -293,6 +302,98 @@
 }
 
 static void
+do_chroot_jail ()
+{
+  /* Now we chroot, setuid/setgrp and chdir. If something goes wrong, we exit 
(this is a
+     security-sensitive area). First we split jail_spec into its components, 
then we
+     retrieve the user/group id (necessarily *before* chroot'ing!) and finally 
we perform
+     the actual actions. */
+
+  char *jail_spec_writable = (char *)malloc (strlen (jail_spec) + 1);
+  strcpy(jail_spec_writable, jail_spec);
+  char *user_name = jail_spec_writable;
+
+  char *group_name = strpbrk (user_name, ",");
+  if (! group_name)
+    {
+      error (_ ("missing group name in jail specification"));
+      exit(1);
+    }
+  *(group_name++) = 0;
+
+  char *jail = strpbrk(group_name, ",");
+  if (! jail)
+    {
+      error (_ ("missing jail directory in jail specification"));
+      exit(1);
+    }
+  *(jail++) = 0;
+
+  char *wd = strpbrk(jail, ",");
+  if (! wd)
+    {
+      error (_ ("missing working directory in jail specification"));
+      exit(1);
+    }
+  *(wd++) = 0;
+
+  if (strpbrk (wd, ","))
+    {
+      error (_ ("too many commas in jail specification"));
+      exit(1);
+    }
+
+  int uid, gid;
+
+  errno = 0;
+  struct passwd *passwd = getpwnam(user_name);
+  if (passwd == NULL)
+    {
+      if (errno == 0) error (_ ("user not found"));
+      else error(_f ("can't get user id from user name (%s)", strerror 
(errno)));
+      exit (3);
+    }
+  uid = passwd->pw_uid;
+
+  errno = 0;
+  struct group *group = getgrnam(group_name);
+  if (group == NULL)
+    {
+      if (errno == 0) error (_ ("group not found"));
+      else error(_f ("can't get group id from group name (%s)", strerror 
(errno)));
+      exit (3);
+    }
+  gid = group->gr_gid;
+
+  if (chroot (jail))
+    {
+      error (_f ("can't chroot (%s)", strerror (errno)));
+      exit (3);
+    }
+
+  if (setgid (gid))
+    {
+      error (_f ("can't change group id (%s)", strerror (errno)));
+      exit (3);
+    }
+
+  if (setuid (uid))
+    {
+      error (_f ("can't change user id (%s)", strerror (errno)));
+      exit (3);
+    }
+
+  if (chdir (wd))
+    {
+      error (_f ("can't change working directory (%s)", strerror (errno)));
+      exit (3);
+    }
+
+  free(jail_spec_writable);
+}
+
+
+static void
 main_with_guile (void *, int, char **)
 {
   /* Engravers use lily.scm contents, need to make Guile find it.
@@ -339,6 +440,8 @@
       exit (2);
     }
 
+  if (jail_spec) do_chroot_jail ();
+
   SCM result = scm_call_1 (ly_scheme_function ("lilypond-main"), files);
   (void) result;
 
@@ -402,6 +505,9 @@
            output_name_global = file_name.to_string ();
          }
          break;
+       case 'j':
+         jail_spec = option_parser->optional_argument_str0_;
+         break;
        case 'e':
          init_scheme_code_string += option_parser->optional_argument_str0_;
          break;
_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to