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
@ -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',
@ -2756,7 +2776,7 @@ $conf->{'attributes'} ||= ['*'];
# Allow command line option --attributes to override settings from
# config file.
if ( $conf->{'cmdline_attributes'} ) {
$conf->{'attributes'} = $conf->{'cmdline_attributes'}
$conf->{'attributes'} = $conf->{'cmdline_attributes'};
}
# create and enter shell loop while also handling Ctrl+C correctly.
@ -2814,7 +2834,7 @@ sub load_config
die "Invalid YAML in $confpath\n" if $@;
if ( $conf2->{'configfile'} and ($confpath eq $conf2->{'configfile'}) ) {
delete $conf2->{'configfile'}
delete $conf2->{'configfile'};
}
$conf2->{alias} ||= {};
@ -2834,7 +2854,7 @@ sub save_config
# 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'}
delete $conf2{'configfile'};
}
YAML::Syck::DumpFile( $confpath, \%conf2 );
chmod 0600, $confpath;