# cpanel - Cpanel/Easy/ModRuid2.pm                Copyright(c) 2014 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

package Cpanel::Easy::ModRuid2;

use strict;

use Cpanel::Easy::Apache::Utils::Support ();
use Cpanel::Version::Compare             ();

my $version      = '0.9.8';
my $url          = 'http://go.cpanel.net/ruid2';
my $chroot_touch = '/var/cpanel/mod_ruid2_chroot_safe';

our $easyconfig = {
    'name'                 => qq{Mod Ruid2 $version},
    'note'                 => qq{See documentation that can found by clicking "More Info" for details},
    'version'              => q{$Rev: 1117 $},
    'verify_on'            => "Detailed documentation for Mod Ruid2 can be found at $url.  Enabling mod_ruid2 automatically disables Cache, Disk Cache, MemCache, mod_mono (.NET 1.x and 2.x), FastCGI, and any MPMs other than the Prefork MPM.  You should not enable mod_ruid2 if you do not know how to administer it.",
    'verify_show_mod_name' => 1,
    'hastargz'             => 1,
    'url'                  => $url,
    'ensurepkg'            => [qw{libcap libcap-devel}],
    'implies'              => {
        'Cpanel::Easy::ModMono'               => 0,
        'Cpanel::Easy::ModMono2'              => 0,
        'Cpanel::Easy::Apache::MPMEvent'      => 0,
        'Cpanel::Easy::Apache::MPMLeader'     => 0,
        'Cpanel::Easy::Apache::MPMPerchild'   => 0,
        'Cpanel::Easy::Apache::MPMThreadpool' => 0,
        'Cpanel::Easy::Apache::MPMWorker'     => 0,
        'Cpanel::Easy::Apache::Fastcgi'       => 0,
        'Cpanel::Easy::Apache::Cache'         => 0,
        'Cpanel::Easy::Apache::DiskCache'     => 0,
        'Cpanel::Easy::Apache::MemCache'      => 0,
        'Cpanel::Easy::PHP5::POSIX'           => 1,    # This is a 'reverse' option, 1 = off
        'Cpanel::Easy::ModJk5'                => 0,    # Case 69681
        'Cpanel::Easy::Tomcat::7_0'           => 0,    # Case 69681
        'Cpanel::Easy::ModPerl'               => 0,    # See ZC-1791
    },
    'when_i_am_off' => sub {
        my ($self) = @_;
        unlink $chroot_touch;
        if ( -e $chroot_touch ) {
            $self->print_alert( q{Could not remove '[_1]': [_2],  that will need done manually!}, $chroot_touch, $! );
        }
    },
    'modself' => sub {
        my $easy       = shift;
        my $self_hr    = shift;
        my $profile_hr = shift;

        $self_hr->{'depends'}{'optmods'}{'Cpanel::Easy::ModPerl'} = 0;    # See ZC-1791

        # We need the virtual host config from 11.31.3 or later
        if ( !-e '/var/cpanel/dev_sandbox' && Cpanel::Version::Compare::compare( $easy->get_cpanel_version(), '<', '11.31.3' ) ) {
            $self_hr->{'hastargz'} = 0;
            $self_hr->{'skip'}     = 1;
            return ( 0, q{Cannot install ModRuid2 on cPanel version 11.30 or earlier} );
        }
    },
    'step' => {
        '0' => {
            'name'    => 'Apply Mailman patch',
            'command' => sub {
                my ($self) = @_;
                my $start  = $self->cwd();
                my $src    = "mod_ruid2";
                my @result;

                chdir $src or return ( 0, q{Could not chdir into '[_1]': [_2]}, $src, $! );

                for my $patch (qw( 0001-mod_ruid2-mailman 0002-mod_ruid2-rgroupinherit )) {
                    @result = $self->apply_patch("../cppatch/$patch.patch");
                    last unless $result[0];
                }

                chdir $start or return ( 0, q{Could not chdir into '[_1]': [_2]}, $start, $! );

                return @result;
            },
        },
        '0.7' => {
            'name'    => 'Set the chroot touch file',
            'command' => sub {
                my ($self) = @_;

                # This file was previously used to indicate that a patch had been applied to mod_ruid2 0.9.4.
                # mod_ruid2 0.9.8 applied the patch upstream, but cPanel still needs the touchfile to indicate
                # that everything is okay.
                if ( !Cpanel::FileUtils::touchfile($chroot_touch) ) {
                    return ( 0, 'Could not create chroot touch file ([_1])', $chroot_touch );
                }
                return ( 1, 'Ok' );
            },
        },
        '1' => {
            'name'    => 'apxsing ruid2 module',
            'command' => sub {
                my ($self) = @_;
                my $path = "mod_ruid2/mod_ruid2.c";
                return $self->run_system_cmd_returnable( [ $self->_get_main_apxs_bin(), qw(-i -a -c -lcap), $path ] );
            },
        },
        '2' => {
            'name'    => 'activating ruid2 module',
            'command' => sub {
                my ($self) = @_;
                $self->ensure_loadmodule_in_httpdconf( 'ruid2', 'mod_ruid2.so' );
                return ( 1, 'Ok' );
            },
        },
        '3' => {
            'name'    => 'ruid2 module httpd.conf setup',
            'command' => sub {
                my ($self) = @_;

                my $new_line = <<"END_RUID2";
<IfModule mod_ruid2.c>
    RMode config
    RDefaultUidGid nobody nobody
    RUidGid nobody nobody
</IfModule>

END_RUID2
                my $file = '/usr/local/apache/conf/mod_ruid2.conf';

                if ( !-e $file ) {
                    if ( open my $inc_fh, '>', $file ) {
                        print {$inc_fh} $new_line;
                        close $inc_fh;
                    }
                    else {
                        return ( 0, q{Could not open() file '[_1]' for writing: [_2]}, $file, $! );
                    }
                }

                $self->strip_from_httpconf('<IfModule mod_ruid2.c>');

                return $self->include_directive_handler(
                    {
                        'include_path' => $file,
                        'addmodule'    => qr{mod_ruid2},
                        'loadmodule'   => qr{ruid2_module},
                    }
                );
            },
        },
    },
};

1;
