#!/usr/bin/perl #^^^^^^^^^^^^^^^^^^^^ Update pathname appropriately to where you have Perl installed # And update the path below of the configuration file as appropriate. $lpinfo_ph = "/usr/local/lprng/info/lpinfo.ph"; #-------------- Should be fairly boilerplate from here on out -------------- # lpinfo_lprm - a Perl script to allow httpd to lprm selected jobs # Copyright 1997, 1998, 1999, 2000 by Alek Komarnitsky, # Use and distribution of this software is covered by the GNU GPL license. # Please see the LICENSE file and http://www.gnu.org/ # Note: this will only work if the print server is running LPRng ... $debug = 0; require 5.002; use Socket; &ReadParse; print "Content-type: text/html\n\n\n" ; print $meta_tags if ( defined($meta_tags)); #Grab stuff from lpinfo.ph ... if ( -r "$lpinfo_ph" ) { require "$lpinfo_ph"; } else { print "could not open $lpinfo_ph - serious error ... \n"; exit(2); } $| = 1; $printer = $in{'printer'}; $jobnumber = $in{'jobnumber'}; if ( defined($in{'printserver'})) { $printserver = $in{'printserver'}; } else { $printserver = "unix"; } $queue_is_nt = $in{'queue_is_nt'} if ( defined($in{'queue_is_nt'})) ; $adminmode = 0; $_ = get_env_variable("^SCRIPT_NAME"); if ( $_ eq $lprmURLadmin ) { $_ = get_env_variable("^REMOTE_USER"); $adminmode = $_; } print "adminmode is $adminmode
" if ($debug); $browserhost="localhost"; $_ = get_env_variable("^REMOTE_ADDR"); print "We got $_ as the REMOTE ADDR
" if ($debug); if ( $queue_is_nt) { $browserhost = $_; } else { if ( $_ ne "" ) { s/^.*=//s; @iplist = split(/\./,$_); $ip = pack('C4',@iplist); $browserhost = gethostbyaddr($ip,AF_INET); } } $browserhost = get_env_variable("^REMOTE_ADDR") if ( $browserhost eq ""); print "We got $browserhost as the browserhost
" if ($debug); if ( (! defined($in{'printer'}) ) || (! defined($in{'jobnumber'}) )) { close_er_out ("Did not get everything in that we needed ...
printer was $printer and $jobnumber was $jobnumber and browserhost was $browserhost and adminmode was $adminmode"); exit(); } print "

printer is $printer and jobnumber is $jobnumber and browserhost is $browserhost and printserver is $printserver and queue_is_nt is $queue_is_nt end
" if ( $debug ); $findjob = &find_job; if ( $findjob =~ "FAILED" ) { &close_er_out("$findjob"); } print "
sending $lprm_suid $adminmode $browserhost $printer $printserver $jobnumber\n" if ($debug); $lprmout = `$lprm_suid $adminmode $browserhost $printer $printserver $jobnumber`; print "

from lprm_suid, we got $lprmout
" if ($debug); if ( $lprmout eq "" ) { &close_er_out("FAILED: lprm returned nothing, which typically means it failed"); } else { #Lets see if it really got removed ... if ($lprmout =~ /Queue Purged/ ) { $findjob = "Could not find any job"; } else { $findjob = &find_job; } print "
second findjob shows $findjob
" if ($debug); if ("$findjob" =~ "Could not find any job" ) { close_er_out("SUCCESS: Print job $jobnumber \@ $jobhost on $printer removed"); } else { close_er_out("FAILED: lprm of job $jobnumber \@ jobhost on $printer failed from $browserhost"); } } print "at the end"; exit(); sub find_job { local(@lpqout,@jobs,$foundrank,$foundjob); if ( defined($in{'queue_is_nt'})) { $command = "$lpq_nt $printer $printserver" ; } else { $command = "$lpq -P$printer $jobnumber"; } print "executing $command
" if ($debug); @lpqout = `$command`; # Parse output and stuff everything below "Rank Owner/ID" into @jobs foreach $_ (@lpqout) { next if ($_ =~ /^\s*$/); if ($foundrank ) { push (@jobs,$_); } $foundrank = 1 if ( $_ =~ "Rank Owner/ID") ; if ($queue_is_nt) { $foundrank = 1 if ( $_ =~ /--------------------/) ; } } # Make sure that we can find the job ... in case user goofs we can tell them that ... foreach $_ (@jobs) { ($rank,$owner,$class,$job,$misc) = split(); print "
rank is $rank owner is $owner class is $class job is $job misc is $misc\n" if ($debug); $foundjob = 1 if (($queue_is_nt) && ( $jobnumber eq "all")); if ( $job eq $jobnumber ) { $foundjob = 1; last; } } if ( ($jobnumber eq "all") && ( $foundrank) ) { return("SUCCESS: all found some jobs"); } if (! $foundjob ) { return ("FAILED: Could not find any job $jobnumber in $printer"); } # Lets see if it truly comes from your machine ... $_ = $owner; s/^.*@(.*)\+.*$/$1/s; tr/A-Z/a-z/; $jobhost = $_; print "jobhost is $jobhost \n" if ( $debug ); if (($jobhost ne $browserhost ) && ( ! ($adminmode) ) ){ close_er_out("FAILED: Print job $jobnumber on $printer came from $jobhost, not your machine $browserhost"); } return ("at the end of findjob"); } sub close_er_out { print "

@_ "; if ( $adminmode ) { print "
"; } else { print ""; } print ""; print ""; print "

"; print ""; exit(); } # HTML parsing ... sub ReadParse { if (@_) { local (*in) = @_; } local ($i, $loc, $key, $val); # Read in text if ($ENV{'REQUEST_METHOD'} eq "GET") { $in = $ENV{'QUERY_STRING'}; } elsif ($ENV{'REQUEST_METHOD'} eq "POST") { for ($i = 0; $i < $ENV{'CONTENT_LENGTH'}; $i++) { $in .= getc; } } @in = split(/&/,$in); foreach $i (0 .. $#in) { # Convert plus's to spaces $_ = $in[$i]; $in[$i] = &sanitize($_); $in[$i] =~ s/\+/ /g; # Convert %XX from hex numbers to alphanumeric $in[$i] =~ s/%(..)/pack("c",hex($1))/ge; # Split into key and value. $loc = index($in[$i],"="); $key = substr($in[$i],0,$loc); $val = substr($in[$i],$loc+1); $in{$key} .= '\0' if (defined($in{$key})); # \0 is the multiple separator $in{$key} .= $val; } } # Added per CERT advistory - send Alek EMail if you want changes here ... sub sanitize { local ($OK_CHARS); $OK_CHARS='-a-zA-Z0-9_.@=?+/ \s'; s/[^$OK_CHARS]/_/go; return $_; } sub get_env_variable{ $env_variable = @_[0]; @env = `env`; @array=(); push(@array,grep(/$env_variable/,@env)); chomp($_ = $array[0]); $_ = &sanitize($_); s/^.*=//s; return $_; }