--- /dev/null
+#!/bin/sh
+# This is the reproducer. Call it as a shell script.
+# To test the sendmail wrapper call it as
+# ./README <wrapper>
+
+set -e
+
+user=${USER-$LOGNAME}
+test -z "$user" && user=$(id -un)
+
+sendmail=${1:-/usr/sbin/sendmail}
+
+
+exec sudo capsh --secbits=0x01 -- -c "date | /usr/sbin/sendmail $user"
--- /dev/null
+#!/usr/bin/env perl
+
+use strict;
+use warnings;
+use feature qw'say';
+use IO::Socket::INET;
+use Pod::Usage;
+use Getopt::Long;
+use Sys::Hostname;
+
+exit main() unless caller;
+
+package X::IO::Socket::INET {
+ use parent 'IO::Socket::INET';
+ use strict;
+ use warnings;
+
+ sub new {
+ my $class = ref $_[0] ? ref shift : shift;
+ my %opt = @_;
+ {
+ no strict 'refs';
+ *{__PACKAGE__ .'::debug'} = delete $opt{Debug} ? sub { say STDERR @_ } : sub {};
+ }
+ return $class->SUPER::new(%opt);
+ }
+
+ sub say {
+ my $self = shift;
+ debug("-> @_");
+ say {$self} @_;
+ }
+
+ sub expect {
+ my $self = shift;
+ my $pattern = shift;
+ $pattern = qr/^$pattern/ unless ref $pattern;
+ my @got;
+ while (<$self>) {
+ chomp;
+ push @got, $_;
+ debug("<- $_");
+ die "$0: unexpected\n"
+ if not /$pattern/;
+ /^\d+-/ and next;
+ last;
+ }
+ return @got;
+ }
+ 1;
+}
+
+sub main {
+
+ my @rcpts;
+ my ($opt_sendmail_t, $opt_from, $opt_debug);
+
+ my $host = hostname or die "$0: Can't get local hostname\n";
+ my $user = getpwuid($<) or die "$0: Can't get user name\n";
+ my $from = "$user\@$host";
+
+ GetOptions(
+ 'debug' => \$opt_debug,
+ 't' => \$opt_sendmail_t,
+ 'f=s' => \$opt_from,
+ ) or pod2usage;
+ @rcpts = @ARGV;
+
+ my $socket = X::IO::Socket::INET->new(
+ PeerAddr => 'localhost',
+ PeerPort => 'smtp',
+ Debug => $opt_debug,
+ ) or die "$0: socket: $!\n";
+
+ $socket->expect(2);
+ $socket->say('EHLO ' . hostname());
+
+ $socket->expect(2);
+ $socket->say("MAIL FROM:<$from>");
+
+ $socket->expect(2);
+
+
+ return 0;
+}
+
+__END__
+
+=head1 NAME
+
+ sendmail - sendmail drop in
+
+=head1 SYNOPSIS
+
+ sendmail [-f <sender>] <recipient>...
+ sendmail -t
+
+=cut