turn find-owner into root daemon so we can open control files
authorDobrica Pavlinusic <dpavlin@rot13.org>
Thu, 7 Mar 2019 08:55:05 +0000 (09:55 +0100)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Thu, 7 Mar 2019 08:55:05 +0000 (09:55 +0100)
cups-pdf-find-owner.pl
cups-pdf-find-owner.sh [new file with mode: 0755]
doc/cups-pdf.txt

index b1754d7..e2ff5ba 100755 (executable)
@@ -6,10 +6,32 @@ use autodie;
 use Data::Dump qw(dump);
 use File::Slurp;
 use DBI;
+use IO::Socket::INET;
 
-open(STDERR, '>>', '/var/log/cups/find_owner_log');
+my $socket = IO::Socket::INET->new(
+       LocalPort => 4001,
+       LocalAddr => 'localhost',
+       Proto => 'tcp',
+       Listen => 5,
+       Reuse => 1
+) or die "ERROR: $!";
 
-my ($file, $local_user, $remote_user) = @ARGV;
+open(my $log, '>>', '/var/log/cups/find_owner_log');
+$SIG{__WARN__} = sub {
+       print STDERR @_;
+       print $log time(), " ", @_;
+};
+
+warn "$0 waiting for client connection on port ", $socket->sockaddr, ":", $socket->sockport, "\n";
+
+while(1) {
+       our $client_socket = $socket->accept();
+       my $line = <$client_socket>;
+
+       warn "<< [$line]";
+
+#my ($file, $local_user, $remote_user) = @ARGV;
+my ($file, $local_user, $remote_user) = split(/\s/,$line,3);
 
 my $job_id = $1 if ( $file =~ m/job_(\d+)/ );
 
@@ -17,6 +39,16 @@ die "can't find job_id in [$file]" unless $job_id;
 
 my $c_file = sprintf "/var/spool/cups/c%05d", $job_id;
 
+if ( ! -e $c_file ) {
+       my $wait = 5; # max s wait for file to appear
+       while ( $wait ) {
+               $0 = "find-owner #$job_id wait $wait s for $c_file";
+               sleep 1;
+               $wait--;
+               last if -e $c_file;
+       }
+}
+
 my $blob = read_file $c_file;
 
 my (undef,$ip) = split(/job-originating-host-name\x00/, $blob, 2);
@@ -57,5 +89,7 @@ $filename_only =~ s/^.*\///; # basename
 my $to = "$spool/$username/$filename_only";
 rename $file, $to;
 warn "# $to";
+$0 = "find-owner #$job_id $username $filename_only"
+
+} # while(1)
 
-exit 0;
diff --git a/cups-pdf-find-owner.sh b/cups-pdf-find-owner.sh
new file mode 100755 (executable)
index 0000000..790fb25
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+echo $* > /dev/tcp/127.0.0.1/4001
+
index c18d982..d6e5aaa 100644 (file)
@@ -6,7 +6,8 @@ PostProcessing hook to look find user from pGinaSessions.
 
 sudo vi /etc/cups/cups-pdf.conf
 
-PostProcessing /srv/safeq/cups-pdf-find-owner.pl
+PostProcessing /srv/safeq/cups-pdf-find-owner.sh
+
 
 
 To make this work, you also have to edit apparmor:
@@ -20,12 +21,29 @@ add permission for script execution:
   /var/spool/cups-pdf/** rw,
 
   # safeq ffzg -- added to allow execution of PostProcessing
-  /srv/safeq/cups-pdf-find-owner.pl uxr,
+  /srv/safeq/cups-pdf-find-owner.sh uxr,
 }
 
 
 
+Replace apparmor roule with updated:
+
 apparmor_parser -r /etc/apparmor.d/usr.sbin.cupsd
 
+Or reload all roules:
+
 /etc/init.d/apparmor restart
 
+
+
+This script will use bash to trigger socket connection with params to
+real implementation which has to wait for a while for cups control file
+to appear since we need it to extract IP address of client machine.
+Another problem is that PostProcessing directive is run as nobody
+and we need root permissions to read control files, so we need to run
+daemon part via sudo:
+
+sudo ./cups-pdf-find-owner.pl
+
+(since suidperl is no longer a thing)
+