]> git.donarmstrong.com Git - lilypond.git/commitdiff
(do_chroot_jail): paranoia security for webserver
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 5 Mar 2005 23:28:34 +0000 (23:28 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sat, 5 Mar 2005 23:28:34 +0000 (23:28 +0000)
use. Patch by Sebastiano Vigna <vigna@dsi.unimi.it>.

ChangeLog
THANKS
VERSION
lily/main.cc

index ed8d1f4407ce9e1b0d2c98825314d7cb8b248e1f..0d52821b11241ce7327bb5ed70aea76c4cff197f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2005-03-06  Han-Wen Nienhuys  <hanwen@xs4all.nl>
+
+       * lily/main.cc (do_chroot_jail): paranoia security for webserver
+       use. Patch by Sebastiano Vigna <vigna@dsi.unimi.it>.
+
 2005-03-05  Han-Wen Nienhuys  <hanwen@xs4all.nl>
 
        * stepmake/bin/add-html-footer.py (do_file): make wiki link optional.
diff --git a/THANKS b/THANKS
index a85931e3f9fbac0ae01e7ddf48e821e5073288a3..bd3534e343fc1cb0a309277e782a2f33a9f72a93 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -23,6 +23,7 @@ Juliusz Chroboczek
 Mats Bengtsson
 Nicolas Sceaux
 Pal Benko
+Sebastiano Vigna
 Tatsuya Ono
 Werner Lemberg
 Yuval Harel
diff --git a/VERSION b/VERSION
index 4871c881c2b52aa859fb1d08c55676bb8e7ed0cd..f2bd041d8b00b99ba720fe1b1f0df77f96f5d59f 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1,6 +1,6 @@
 PACKAGE_NAME=LilyPond
 MAJOR_VERSION=2
 MINOR_VERSION=5
-PATCH_LEVEL=13
+PATCH_LEVEL=14
 MY_PATCH_LEVEL=
 
index ce313b93d17cc05ec35bdd166dc7e0fe0e3854cb..7ef3b516ff5ffa709a29ba984171458d8bacada2 100644 (file)
@@ -109,6 +109,9 @@ _i ("    This program is free software; you can redistribute it and/or\n"
    LOCAL_LILYPOND_DATADIR = /usr/share/lilypond/<VERSION> */
 char const *prefix_directories[] = {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;
 
@@ -129,6 +132,7 @@ static Long_option_init options_static[] =
     {_i ("DIR"), "include", 'I',  _i ("add DIR to search path")},
     {_i ("FILE"), "init", 'i',  _i ("use FILE as init file")},
     {_i ("FILE"), "output", 'o',  _i ("write output to FILE (suffix will be added)")},
+    {_i ("USER,GROUP,JAIL,DIR"), "jail", 'j', _i ("chroot to JAIL, become USER:GROUP and cd into DIR")},
     {0, "preview", 'p',  _i ("generate a preview")},
     {0, "no-pages", 0,  _i ("don't generate full pages")},
     {0, "png", 0,  _i ("generate PNG")},
@@ -251,6 +255,82 @@ void init_global_tweak_registry ();
 void init_fontconfig ();
 
 
+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 **)
 {
@@ -303,6 +383,9 @@ main_with_guile (void *, int, char **)
       exit (2);
     }
 
+  if (! jail_spec.is_empty ()) 
+     do_chroot_jail ();
+
   SCM result = scm_call_1 (ly_lily_module_constant ("lilypond-main"), files);
   (void) result;
 
@@ -373,6 +456,9 @@ parse_argv (int argc, char **argv)
            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;