On Sun, 2005-03-06 at 00:04 +0100, Han-Wen Nienhuys wrote:

> If you resend with this change, I will apply the patch.
> 

Here it is.
-- 
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-06 00:11:43.538455556 +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"
 
@@ -30,6 +35,7 @@
 #include "misc.hh"
 #include "output-def.hh"
 #include "string.hh"
+#include "string-convert.hh"
 #include "warn.hh"
 
 /*
@@ -115,6 +121,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. */
+String jail_spec;
+
 /*  The option parser */
 static Getopt_long *option_parser = 0;
 
@@ -133,6 +142,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 +303,82 @@
 }
 
 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. */
+
+  Array<String> components = String_convert::split(jail_spec, ',');
+  if (components.size() < 3)
+    {
+      error (_ ("too few elements in jail specification"));
+      exit(1);
+    }
+  if (components.size() > 4)
+    {
+      error (_ ("too many elements in jail specification"));
+      exit(1);
+    }
+
+  int uid, gid;
+  char *user_name = components[0].get_str0 ();
+  char *group_name = components[1].get_str0 ();
+  char *jail = components[2].get_str0 ();
+  char *wd = components[3].get_str0 ();
+
+  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);
+    }
+}
+
+
+static void
 main_with_guile (void *, int, char **)
 {
   /* Engravers use lily.scm contents, need to make Guile find it.
@@ -339,6 +425,9 @@
       exit (2);
     }
 
+  if (! jail_spec.is_empty ()) 
+    do_chroot_jail ();
+
   SCM result = scm_call_1 (ly_scheme_function ("lilypond-main"), files);
   (void) result;
 
@@ -402,6 +491,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