--- loncom/cgi/lonauthcgi.pm 2009/08/21 23:14:06 1.4 +++ loncom/cgi/lonauthcgi.pm 2011/10/17 17:23:25 1.8 @@ -1,7 +1,7 @@ # # LON-CAPA authorization for cgi-bin scripts # -# $Id: lonauthcgi.pm,v 1.4 2009/08/21 23:14:06 raeburn Exp $ +# $Id: lonauthcgi.pm,v 1.8 2011/10/17 17:23:25 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -32,7 +32,7 @@ =head1 NAME -loncgi +lonauthcgi =head1 SYNOPSIS @@ -55,6 +55,7 @@ package LONCAPA::lonauthcgi; use strict; use lib '/home/httpd/lib/perl'; +use Socket; use Apache::lonnet; use Apache::lonlocal; use LONCAPA; @@ -72,11 +73,16 @@ Inputs: $page, the identifier of the pag $ip, the IP address of the client requesting the page. Returns: 1 if access is permitted for the requestor's IP. - Access is allowed if on of the following is true: - (a) the requestor IP is the loopback address - (b) Domain configurations for domains hosted on this server include + Access is allowed if one of the following is true: + (a) the requestor IP is the loopback address. + (b) the requestor IP is the IP of the current server. + (c) the requestor IP is the IP of a manager, + if the page to view is not "takeoffline" or "toggledebug" + (d) the requestor IP is the IP of a server belonging + to a domain included in domains hosted on this server. + (e) Domain configurations for domains hosted on this server include the requestor's IP as one of the specified IPs with access - to this page. (does not apply to 'ping' page type) + to this page. (not applicable to 'ping' page). =cut @@ -88,12 +94,27 @@ sub check_ipbased_access { if (!defined($ip)) { $ip = $ENV{'REMOTE_ADDR'}; } - if (($page ne 'lonstatus') && ($page ne 'serverstatus')) { - if ($ip eq '127.0.0.1') { + if ($ip eq '127.0.0.1') { + $allowed = 1; + return $allowed; + } else { + my $lonhost = $Apache::lonnet::perlvar{'lonHostID'}; + my $host_ip = &Apache::lonnet::get_host_ip($lonhost); + if (($host_ip ne '') && ($host_ip eq $ip)) { + $allowed = 1; + return $allowed; + } + } + if (&is_manager_ip($ip)) { + unless (($page eq 'toggledebug') || ($page eq 'takeoffline')) { $allowed = 1; return $allowed; } } + if (&check_domain_ip($ip)) { + $allowed = 1; + return $allowed; + } if ($page ne 'ping') { my @poss_domains = &Apache::lonnet::current_machine_domains(); foreach my $dom (@poss_domains) { @@ -119,6 +140,87 @@ sub check_ipbased_access { =pod +=item is_manager_ip() + +Inputs: $remote_ip, the IP address of the client requesting the page. + +Returns: 1 if the client IP address corresponds to that of a + machine listed in /home/httpd/lonTabs/managers.tab + +=cut + +############################################# +############################################# +sub is_manager_ip { + my ($remote_ip) = @_; + return if ($remote_ip eq ''); + my ($directory,$is_manager); + foreach my $key (keys(%Apache::lonnet::managerstab)) { + my $manager_ip; + if ($key =~ /:/) { + my ($cluname,$dnsname) = split(/:/,$key); + my $ip = gethostbyname($dnsname); + if (defined($ip)) { + $manager_ip = inet_ntoa($ip); + } + } else { + $manager_ip = &Apache::lonnet::get_host_ip($key); + } + if (defined($manager_ip)) { + if ($remote_ip eq $manager_ip) { + $is_manager = 1; + last; + } + } + } + return $is_manager; +} + +############################################# +############################################# + +=pod + +=item check_domain_ip() + +Inputs: $remote_ip, the IP address of the client requesting the page. + +Returns: 1 if the client IP address is for a machine in the cluster + and domain in common for client machine and this machine. + +=cut + +############################################# +############################################# +sub check_domain_ip { + my ($remote_ip) = @_; + my %remote_doms; + my $allowed; + if ($remote_ip ne '') { + if (&Apache::lonnet::hostname($remote_ip) ne '') { + my @poss_domains = &Apache::lonnet::current_machine_domains(); + if (@poss_domains > 0) { + my @remote_hosts = &Apache::lonnet::get_hosts_from_ip($remote_ip); + foreach my $hostid (@remote_hosts) { + my $hostdom = &Apache::lonnet::host_domain($hostid); + if ($hostdom ne '') { + if (grep(/^\Q$hostdom\E$/,@poss_domains)) { + $allowed = 1; + last; + } + } + } + } + } + } + return $allowed; +} + +############################################# +############################################# + +=pod + =item can_view() Inputs: $page, the identifier of the page to be viewed, @@ -133,14 +235,12 @@ Returns: 1 if access to the page is perm the requestor as one of the named users (username:domain) with access to the page. - In the case of requests for the 'ping' page, access is also allowed if - at least one domain hosted on requestor's server is also hosted on this server. - In the case of requests for the 'showenv' page (/adm/test), the domains tested are not the domains hosted on the server, but instead are a single domain - the domain of the requestor. In addition, if the requestor has an active Domain Coordinator role for that domain, access is permitted, regardless of the requestor's current role. + =cut ############################################# @@ -150,16 +250,6 @@ sub can_view { my $allowed; if ($Apache::lonnet::env{'request.role'} =~ m{^su\./}) { $allowed = 1; - } elsif ($page eq 'ping') { - my @poss_domains = &Apache::lonnet::current_machine_domains(); - my @hostids= &Apache::lonnet::get_hosts_from_ip($ENV{'REMOTE_ADDR'}); - foreach my $hostid (@hostids) { - my $hostdom = &Apache::lonnet::host_domain($hostid); - if (grep(/^\Q$hostdom\E$/,@poss_domains)) { - $allowed = 1; - last; - } - } } else { my @poss_domains; if ($page eq 'showenv') { @@ -206,7 +296,7 @@ sub can_view { =pod -=unauthorized_msg() +=item unauthorized_msg() Inputs: $page, the identifier of the page to be viewed, can be one of the keys in the hash from &serverstatus_titles() @@ -270,11 +360,16 @@ sub serverstatus_titles { 'metadata_harvest' => 'Harvest Metadata Searches', 'takeoffline' => 'Offline - replace Log-in page', 'takeonline' => 'Online - restore Log-in page', - 'showenv' => "Show user environment", + 'showenv' => 'Show user environment', + 'toggledebug' => 'Toggle debug messages', ); return \%titles; } +=pod + +=back -1; +=cut +1;