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