![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /proc/self/root/opt/cpanel/ea-podman/lib/ea_podman/ |
#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - ea_podman/subids.pm Copyright 2022 cPanel, L.L.C. # All rights Reserved. # [email protected] http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited use strict; use warnings; package ea_podman::subids; use Path::Tiny 'path'; use Cpanel::OS; our $good = "✅"; our $bad = "❌"; # FOR Testability our $file_subuid = "/etc/subuid"; our $file_subgid = "/etc/subgid"; our $dir_run = "/run/user"; sub ensure_user_root { my ( $user, $num_uids ) = @_; $num_uids = 65537 if !$num_uids; my $subuid = get_subuids(); my $subgid = get_subgids(); return if exists $subuid->{$user} && exists $subgid->{$user}; # via the mechanics this means the uids/gids start at 190000 my $getuid_max = 190000 - $num_uids; my $getgid_max = 190000 - $num_uids; foreach my $u ( keys %{$subuid} ) { my ( $uid, $range ) = split( /:/, $subuid->{$u} ); $uid += $range; $getuid_max = $uid if ( $uid > $getuid_max ); } foreach my $u ( keys %{$subgid} ) { my ( $uid, $range ) = split( /:/, $subgid->{$u} ); $uid += $range; $getgid_max = $uid if ( $uid > $getgid_max ); } $getuid_max++; $getgid_max++; my $num_uids_minus_one = $num_uids - 1; if ( !exists $subuid->{$user} ) { if ( open my $fh, ">>", $file_subuid ) { print $fh "$user:$getuid_max:$num_uids_minus_one\n"; close $fh; } } if ( !exists $subgid->{$user} ) { if ( open my $fh, ">>", $file_subgid ) { print $fh "$user:$getgid_max:$num_uids_minus_one\n"; close $fh; } } # best effort mkdir $dir_run; my ( $uid, $gid ) = ( getpwnam($user) )[ 2, 3 ]; mkdir( "$dir_run/$uid", 0700 ); chown( $uid, $gid, "$dir_run/$uid" ); if ( !-d "$dir_run/$uid" ) { die "The directory “$dir_run/$uid” is missing and could not be created (mode: 0700; owner & group: $user).\n"; } # Tell podman to ignore uid/gid issues _ensure_storage_conf(); return; } sub assert_has_user_namespaces { my ($verbose) = @_; chomp( my $max_uns = `sysctl --values user.max_user_namespaces 2>/dev/null` ); if ( !$max_uns ) { my $c7_msg = <<'C7'; • On CentOS 7 running these command enable user namespaces: 1. grubby --args="namespce.unpriv_enable=1 user_namespace.enable=1" --update-kernel="$(grubby --default-kernel)" 2. echo "user.max_user_namespaces=15076" >> /etc/sysctl.conf 3. reboot C7 chomp($c7_msg); # I wish there was a better way … my $os = -f '/etc/os-release' ? `source /etc/os-release; echo \$ID\$VERSION_ID` : "??"; chomp($os); $c7_msg = "" if $os ne "centos7"; die <<"END_NO_UNS"; $bad User Namespaces not available (`sysctl --values user.max_user_namespaces`): • Container based packages will not work until they are. • To learn more read `man user_namespaces`$c7_msg END_NO_UNS } print "$good user.max_user_namespaces = '$max_uns'\n" if $verbose; return $max_uns; } sub get_subuids { return _parse_subid_file($file_subuid); } sub get_subgids { return _parse_subid_file($file_subgid); } ############### #### helpers ## ############### sub _parse_subid_file { my ($file) = @_; my $hr = {}; for my $line ( path($file)->lines( { chomp => 1 } ) ) { my ( $user, $ranges ) = split( ":", $line, 2 ); warn "“$user” is in “$file” more than once!\n" if exists $hr->{$user}; $hr->{$user} = $ranges; } return $hr; } sub _ensure_storage_conf { # This is only necessary on certain OS's. # UGMO: # Since we can only extend Cpanel::OS for new versions of ULC we can’t use a proper OS agnostic attribute like `if (Cpanel::OS::container_storage_overlay_ignore_chown_errors) { ` # That being the case we have to violate the point of Cpanel::OS and do an isolated one off here :/ if ( Cpanel::OS::distro() eq "ubuntu" && Cpanel::OS::major() eq "22" ) { my $conf = path('/etc/containers/storage.conf'); if ( !$conf->exists() ) { $conf->spew( qq{[storage] driver = "overlay" runroot = "/run/containers/storage" graphroot = "/var/lib/containers/storage" [storage.options] ignore_chown_errors = "true" } ); } } return; } 1;