@@ -23,6 +23,7 @@
use strict;
use warnings;
+use POSIX;
use Sys::Syslog;
my $log_ident = 'cifs-upcall-helper';
@@ -33,6 +34,15 @@ my $log_level = 0;
# 2 - verbose debugging (LOG_INFO)
my $keyid;
+my %key_vars;
+
+# keyctl rdescribe output format:
+# cifs.spnego;0;0;39010000;ver=0x2;host=vm1;ip4=192.168.122.73;sec=krb5;uid=0x0;creduid=0x0;user=user1;pid=0xbaf7d;upcall_target=mount
+#
+# user=<username> is optional
+# upcall_target=(mount|app) is optional
+my $key_descriptionv2_re = qr/^cifs.spnego;([0-9]+);([0-9]+);([0-9a-f]+);ver=0x2;host=([^;]+);(ip4|ip6)=([^;]+);sec=(krb5|mskrb5|iakerb);uid=(0x[0-9a-f]+);creduid=(0x[0-9a-f]+)(?:;user=([^;]+))?;pid=(0x[0-9a-f]+)(?:;upcall_target=(mount|app))?$/;
+my @descriptionv2_keys = ('keyuid', 'keygid', 'perms', 'host', 'ipv', 'ip', 'sec', 'uid', 'creduid', 'user', 'pid', 'upcall_target');
sub log_msg {
my $msg_level = shift;
@@ -58,6 +68,43 @@ sub exec_upcall {
log_msg 1, sprintf("executing cifs.upcall: %s", join(' ', @upcall_args));
exec { $upcall_args[0] } @upcall_args;
}
+sub get_key_description {
+ my $keyid = shift;
+
+ if (! open KEYCTL, "/usr/bin/keyctl rdescribe $keyid 2>&1 |") {
+ log_msg 0, "Error executing keyctl: $!";
+ exec_upcall;
+ }
+ my $rdescribe = <KEYCTL>;
+ chomp $rdescribe;
+ close KEYCTL;
+ if ($?) {
+ log_msg 0, "Error executing keyctl: $rdescribe";
+ exec_upcall;
+ }
+
+ log_msg 2, "description for key $keyid: $rdescribe";
+ return $rdescribe;
+}
+sub parse_key_description {
+ my $key_description_str = shift;
+ if ($key_description_str !~ $key_descriptionv2_re) {
+ log_msg 0, "could not match key description to known format: $key_description_str";
+ log_msg 1, "executing upcall with default parameters";
+ exec_upcall;
+ }
+ @key_vars{@descriptionv2_keys} = $key_description_str =~ $key_descriptionv2_re;
+
+ $key_vars{'uid'} = scalar POSIX::strtol($key_vars{'uid'}, 16);
+ $key_vars{'creduid'} = scalar POSIX::strtol($key_vars{'creduid'}, 16);
+ $key_vars{'user'} = '' if !defined $key_vars{'user'};
+ $key_vars{'upcall_target'} = '' if !defined $key_vars{'upcall_target'};
+ log_msg 1, sprintf("description for key %d keyuid: %d, keygid: %d, perms: %d, host %s, ipv: %s, ip: %s, sec: %s, uid: %d, creduid: %d, user %s, upcall_target: %s",
+ $keyid, $key_vars{'keyuid'}, $key_vars{'keygid'}, $key_vars{'perms'},
+ $key_vars{'host'}, $key_vars{'ipv'}, $key_vars{'ip'},
+ $key_vars{'sec'}, $key_vars{'uid'}, $key_vars{'creduid'},
+ $key_vars{'user'}, $key_vars{'upcall_target'});
+}
if ($#ARGV ne 0) {
if (-t STDOUT) {
@@ -71,4 +118,6 @@ $keyid = $ARGV[0];
log_msg 1, "$log_ident - keyid: $keyid";
+my $key_description_str = get_key_description $keyid;
+parse_key_description $key_description_str;
exec_upcall;
Execute keyctl to get the key's description, and parse the description fields, assigning to key_vars for use during matching. Still just executing the upcall with keyid. Signed-off-by: Frank Sorenson <sorenson@redhat.com> --- contrib/upcall-helper/cifs-upcall-helper | 49 ++++++++++++++++++++++++ 1 file changed, 49 insertions(+)