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