Fix sasl for DIGEST-MD5, PLAIN, and LOGIN mechanisms, which I don't think ever actually worked properly.

Add a sasluser argument if a specific identity is required for the
backend, which if unsupplied, tries to guess if a binddn is present.

(Uwe's previous commit fixed EXTERNAL and GSSAPI, which did work, but
randomly failed due to hash ordering.)


Minor style cleanups, remove duplicate/unecessary logic for anonymous
binds.

FossilOrigin-Name: b2bc73d1b624235cf17da960a5e3fd0df9c0ed714bc5f71db2cbea6009f255d5
This commit is contained in:
Mahlon E. Smith 2019-10-13 17:44:16 +00:00
parent 14974b8a9f
commit b9098f4e53
2 changed files with 41 additions and 20 deletions

View file

@ -17,5 +17,6 @@ Peter Marschall <peter@adpm.de>
Rick H. <rickh_shelldap@printstring.com>
Rong-En Fan <rafan@FreeBSD.org>
Salvatore Bonaccorso <carnil@debian.org>
Uwe Kleine-König <uwe@kleine-koenig.org>
Yann Cezard <yann.cezard@univ-pau.fr>

View file

@ -166,7 +166,20 @@ credentials.
A space separated list of SASL mechanisms. Requires the Authen::SASL
module.
--sasl 'PLAIN CRAM-MD5 GSSAPI'
--sasl 'PLAIN DIGEST-MD5 EXTERNAL GSSAPI'
-Y 'PLAIN DIGEST-MD5 EXTERNAL GSSAPI'
=back
=over 4
=item B<sasluser>
SASL authorization identity, if one is explicitly required by your
backend mechanism.
--sasluser mahlon
-X mahlon
=back
@ -709,8 +722,8 @@ sub ldap
You may try connecting insecurely, or install the module and try again.\n} if $@;
}
if ($conf->{'binddn'}) {
if($conf->{'promptpass'}) {
if ( $conf->{'binddn'} ) {
if ( $conf->{'promptpass'} ) {
# Prompt for a password after disabling local echo.
#
print "Bind password: ";
@ -718,9 +731,11 @@ You may try connecting insecurely, or install the module and try again.\n} if $@
chomp( $conf->{'bindpass'} = <STDIN> );
Term::ReadKey::ReadMode 0;
print "\n";
} elsif($conf->{'pass'}) {
}
elsif ( $conf->{'pass'} ) {
$conf->{'bindpass'} = $conf->{'pass'}
} elsif($conf->{'passfile'}) {
}
elsif ( $conf->{'passfile'} ) {
chomp( $conf->{'bindpass'} = slurp($conf->{'passfile'}));
}
}
@ -762,16 +777,20 @@ You may try connecting insecurely, or install the module and try again.\n} if $@
if ( $use_sasl ) {
my $serv = $conf->{'server'};
$serv =~ s!^ldap[si]?://!!;
$sasl = Authen::SASL->new( mechanism => $conf->{'sasl'} );
my $user = $1 if $conf->{'binddn'} && $conf->{'binddn'} =~ /uid=([^,]*),/i;
my $callback = {
pass => $conf->{'bindpass'},
user => $conf->{'sasluser'} || $user
};
$sasl = Authen::SASL->new( mechanism => $conf->{'sasl'}, callback => $callback );
$sasl_conn = $sasl->client_new( 'ldap', $serv );
}
# bind with sasl
#
if ( $sasl_conn ) {
$rv = $ldap->bind( $conf->{'binddn'},
sasl => $sasl_conn
);
$rv = $ldap->bind( $conf->{'binddn'}, sasl => $sasl_conn );
}
# simple bind as an authenticated dn
@ -785,7 +804,7 @@ You may try connecting insecurely, or install the module and try again.\n} if $@
# bind anonymously
#
else {
$rv = $sasl_conn ? $ldap->bind( sasl => $sasl_conn ) : $ldap->bind();
$rv = $ldap->bind();
}
my $err = $rv->error();
@ -2715,9 +2734,10 @@ Getopt::Long::GetOptions(
'passfile|y=s',
'timeout=i',
'sasl|Y=s',
'sasluser|X=s',
'simple|x!' => sub {
my($opt,$arg) = @_;
$conf->{sasl} = $arg ? undef : 'PLAIN CRAM-MD5 GSSAPI'
$conf->{sasl} = $arg ? undef : 'PLAIN DIGEST-MD5 GSSAPI'
},
'tls_cacert=s',
'tls_cert=s',
@ -2755,8 +2775,8 @@ $conf->{'attributes'} ||= ['*'];
# Allow command line option --attributes to override settings from
# config file.
if($conf->{'cmdline_attributes'}) {
$conf->{'attributes'} = $conf->{'cmdline_attributes'}
if ( $conf->{'cmdline_attributes'} ) {
$conf->{'attributes'} = $conf->{'cmdline_attributes'};
}
# create and enter shell loop while also handling Ctrl+C correctly.
@ -2774,9 +2794,9 @@ sub ctrl_c_handler {
}
my $sigaction = POSIX::SigAction->new( \&ctrl_c_handler, $sigset, 0);
my $old_action = POSIX::SigAction->new;
POSIX::sigaction(&POSIX::SIGINT, $sigaction, $old_action); # save default one
POSIX::sigaction( &POSIX::SIGINT, $sigaction, $old_action ); # save default one
$shell->cmdloop();
POSIX::sigaction(&POSIX::SIGINT, $old_action); # restore default one
POSIX::sigaction( &POSIX::SIGINT, $old_action ); # restore default one
### List of default config files
###
@ -2813,13 +2833,13 @@ sub load_config
my $conf2 = eval { YAML::Syck::Load( $data ) };
die "Invalid YAML in $confpath\n" if $@;
if( $conf2->{'configfile'} and ($confpath eq $conf2->{'configfile'})) {
delete $conf2->{'configfile'}
if ( $conf2->{'configfile'} and ($confpath eq $conf2->{'configfile'}) ) {
delete $conf2->{'configfile'};
}
$conf2->{alias} ||= {};
return($confpath, $conf2);
return( $confpath, $conf2 );
}
### dump YAML config into conf file while making sure that
@ -2833,8 +2853,8 @@ sub save_config
my %conf2 = %$conf;
# This check is currently unnecessary because the comparison will always
# be true, but is left here for effect of least surprise in the future.
if( $conf->{configfile} and ($confpath eq $conf->{configfile})) {
delete $conf2{'configfile'}
if ( $conf->{configfile} and ($confpath eq $conf->{configfile}) ) {
delete $conf2{'configfile'};
}
YAML::Syck::DumpFile( $confpath, \%conf2 );
chmod 0600, $confpath;