diff --git a/ldap-server/CHANGELOG b/ldap-server/CHANGELOG
index e1bc205c3..1e2729717 100644
--- a/ldap-server/CHANGELOG
+++ b/ldap-server/CHANGELOG
@@ -2,3 +2,6 @@
First version of this module, for configuring the OpenLDAP server and managing its database.
---- Changes since 1.400 ----
Added an option to create an example LDAP group, and made the example user a person.
+---- Changes since 1.440 ----
+The protocols served by the LDAP server, such as SSL and non-encrypted, can now be set on the OpenLDAP Server Configuration page. This is only possible on Redhat and Debian-derived systems though, as the protocols are configured in the init script.
+Fixed a bug that prevented browsing of the LDAP database in SSL mode, thanks to Paul R. Ganci.
diff --git a/ldap-server/edit_slapd.cgi b/ldap-server/edit_slapd.cgi
index c9c113ae5..026e9f9e3 100644
--- a/ldap-server/edit_slapd.cgi
+++ b/ldap-server/edit_slapd.cgi
@@ -86,6 +86,17 @@ print &ui_hidden_table_end("basic");
# SSL section
print &ui_hidden_table_start($text{'slapd_header2'}, undef, 2, "ssl", 0, \@tds);
+# Protocols to serve
+if (&can_get_ldap_protocols()) {
+ $protos = &get_ldap_protocols();
+ @protos = sort { $a cmp $b } keys %$protos;
+ print &ui_table_row($text{'slapd_protos'},
+ &ui_select("protos",
+ [ grep { $protos->{$_} } @protos ],
+ [ map { [ $_, $text{'slapd_'.$_} ] } @protos ],
+ scalar(@protos), 1));
+ }
+
# SSL file options
$anycert = 0;
foreach $s ([ 'TLSCertificateFile', 'cert' ],
diff --git a/ldap-server/lang/en b/ldap-server/lang/en
index 850f3ce53..2300ce2cc 100644
--- a/ldap-server/lang/en
+++ b/ldap-server/lang/en
@@ -73,6 +73,10 @@ slapd_gencert=Generate SSL Certificate
slapd_gencertdesc=To run your LDAP server in TLS mode, an SSL certificate and private key must first be generated. Click this button to create a self-signed certificate for your system.
slapd_gencertwarn=Warning - your existing certificate will no longer be used.
slapd_ecannot=You are not allowed to configure the LDAP server
+slapd_protos=LDAP connections to accept
+slapd_ldap=LDAP over network
+slapd_ldaps=LDAP over SSL
+slapd_ldapi=Unix socket file
schema_title=Manage Schema
schema_file=Name
diff --git a/ldap-server/ldap-server-lib.pl b/ldap-server/ldap-server-lib.pl
index 8b1f90504..b7346b365 100644
--- a/ldap-server/ldap-server-lib.pl
+++ b/ldap-server/ldap-server-lib.pl
@@ -36,13 +36,13 @@ if ($net_ldap_error) {
}
# Work out server name, login and TLS mode
-local ($server, $port, $user, $pass, $ssl) = @_;
+local ($server, $port, $user, $pass, $ssl);
if ($config{'server'}) {
# Remote box .. everything must be set
$server = $config{'server'};
gethostbyname($server) || return &text('connect_eserver',
"$server");
- $port = $config{'port'} || 389;
+ $port = $config{'port'};
$user = $config{'user'};
$user || return $text{'connect_euser'};
$pass = $config{'pass'};
@@ -54,7 +54,7 @@ else {
"$config{'config_file'}");
local $conf = &get_config();
$server = "127.0.0.1";
- $port = $config{'port'} || &find_value("port", $conf) || 389;
+ $port = $config{'port'} || &find_value("port", $conf);
$user = $config{'user'} || &find_value("rootdn", $conf);
$user || return $text{'connect_euser2'};
$pass = $config{'pass'} || &find_value("rootpw", $conf);
@@ -67,26 +67,28 @@ $ssl = $config{'ssl'};
local @ssls = $ssl eq "" ? ( 1, 0 ) : ( $ssl );
local $ldap;
foreach $ssl (@ssls) {
- $ldap = Net::LDAP->new($server, port => $port);
+ my $sslport = $port ? $port : $ssl ? 636 : 389;
+ $ldap = Net::LDAP->new($server, port => $sslport,
+ scheme=>$ssl ? 'ldaps' : 'ldap');
if (!$ldap) {
# Connection failed .. give up completely
- return &text('connect_eldap', "$server", $port);
+ return &text('connect_eldap', "$server", $sslport);
}
if ($ssl) {
- # Switch to TLS mode
+ # Switch to TLS mode. It is OK if this fails though
local $mesg;
eval { $mesg = $ldap->start_tls(); };
- if ($@ || !$mesg || $mesg->code) {
- # Failed to switch to SSL mode. If also trying non-SSL,
- # continue around the loop. Otherwise, give up
- if (@ssls > 1) {
- next;
- }
- else {
- return &text('connect_essl', "$server",
- $@ ? $@ : &ldap_error($mesg));
- }
- }
+ #if ($@ || !$mesg || $mesg->code) {
+ # # Failed to switch to SSL mode. If also trying non-SSL,
+ # # continue around the loop. Otherwise, give up
+ # if (@ssls > 1) {
+ # next;
+ # }
+ # else {
+ # return &text('connect_essl', "$server",
+ # $@ ? $@ : &ldap_error($mesg));
+ # }
+ # }
}
}
$ldap || return "This can't happen!";
@@ -527,5 +529,89 @@ foreach my $b (@{$p->{'by'}}) {
$a->{'values'} = \@v;
}
+# can_get_ldap_protocols()
+# Returns 1 if we can get the protocols this LDAP server will serve. Depends
+# on the OS, as this is often set in the init script.
+sub can_get_ldap_protocols
+{
+return $gconfig{'os_type'} eq 'redhat-linux' &&
+ -r "/etc/sysconfig/ldap" ||
+ $gconfig{'os_type'} eq 'debian-linux' &&
+ -r "/etc/default/slapd" &&
+ &get_ldap_protocols();
+}
+
+# get_ldap_protocols()
+# Returns a hash from known LDAP protcols (like ldap, ldaps and ldapi) to
+# flags indicating if they are enabled
+sub get_ldap_protocols
+{
+if ($gconfig{'os_type'} eq 'redhat-linux') {
+ # Stored in /etc/sysconfig/ldap file
+ local %ldap;
+ &read_env_file("/etc/init.d/ldap", \%ldap);
+ &read_env_file("/etc/sysconfig/ldap", \%ldap);
+ return { 'ldap' => $ldap{'SLAPD_LDAP'} eq 'yes' ? 1 : 0,
+ 'ldapi' => $ldap{'SLAPD_LDAPI'} eq 'yes' ? 1 : 0,
+ 'ldaps' => $ldap{'SLAPD_LDAPS'} eq 'yes' ? 1 : 0,
+ };
+ }
+elsif ($gconfig{'os_type'} eq 'debian-linux') {
+ # Stored in /etc/default/slapd, in SLAPD_SERVICES line
+ local %ldap;
+ &read_env_file("/etc/default/slapd", \%ldap);
+ if ($ldap{'SLAPD_SERVICES'}) {
+ local @servs = split(/\s+/, $ldap{'SLAPD_SERVICES'});
+ local $rv = { 'ldap' => 0, 'ldaps' => 0, 'ldapi' => 0 };
+ foreach my $w (@servs) {
+ if ($w =~ /^(ldap|ldaps|ldapi):\/\/\/$/) {
+ $rv->{$1} = 1;
+ }
+ else {
+ # Unknown protocol spec .. ignore
+ return undef;
+ }
+ }
+ return $rv;
+ }
+ else {
+ # Default is non-encrypted only
+ return { 'ldap' => 1, 'ldaps' => 0, 'ldapi' => 0 };
+ }
+ }
+}
+
+# save_ldap_protocols(&protos)
+# Updates the OS-specific file containing enabled LDAP protocols. Also does
+# locking on the file.
+sub save_ldap_protocols
+{
+local ($protos) = @_;
+if ($gconfig{'os_type'} eq 'redhat-linux') {
+ # Stored in /etc/sysconfig/ldap file
+ local %ldap;
+ &lock_file("/etc/sysconfig/ldap");
+ &read_env_file("/etc/sysconfig/ldap", \%ldap);
+ $ldap{'SLAPD_LDAP'} = $protos->{'ldap'} ? 'yes' : 'no'
+ if (defined($protos->{'ldap'}));
+ $ldap{'SLAPD_LDAPI'} = $protos->{'ldapi'} ? 'yes' : 'no'
+ if (defined($protos->{'ldapi'}));
+ $ldap{'SLAPD_LDAPS'} = $protos->{'ldaps'} ? 'yes' : 'no'
+ if (defined($protos->{'ldaps'}));
+ &write_env_file("/etc/sysconfig/ldap", \%ldap);
+ &unlock_file("/etc/sysconfig/ldap");
+ }
+elsif ($gconfig{'os_type'} eq 'debian-linux') {
+ # Update /etc/default/slapd SLAPD_SERVICES line
+ local %ldap;
+ &lock_file("/etc/default/slapd");
+ &read_env_file("/etc/default/slapd", \%ldap);
+ $ldap{'SLAPD_SERVICES'} =
+ join(" ", map { $_.":///" } grep { $protos->{$_} } keys %$protos);
+ &write_env_file("/etc/default/slapd", \%ldap);
+ &unlock_file("/etc/default/slapd");
+ }
+}
+
1;
diff --git a/ldap-server/save_slapd.cgi b/ldap-server/save_slapd.cgi
index 6dfb39f0a..e5e814394 100644
--- a/ldap-server/save_slapd.cgi
+++ b/ldap-server/save_slapd.cgi
@@ -65,6 +65,12 @@ else {
&save_directive($conf, 'timelimit', $in{'timelimit'});
}
+# LDAP protocols
+if (&can_get_ldap_protocols()) {
+ @newprotos = split(/\0/, $in{'protos'});
+ @newprotos || &error($text{'slapd_eprotos'});
+ }
+
# SSL file options
foreach $s ([ 'TLSCertificateFile', 'cert' ],
[ 'TLSCertificateKeyFile', 'key' ],
@@ -87,6 +93,16 @@ if ($save_config) {
&save_module_config();
&unlock_file($module_config_file);
}
+if (&can_get_ldap_protocols()) {
+ $protos = &get_ldap_protocols();
+ foreach $p (keys %$protos) {
+ $protos->{$p} = 0;
+ }
+ foreach $p (@newprotos) {
+ $protos->{$p} = 1;
+ }
+ &save_ldap_protocols($protos);
+ }
&webmin_log('slapd');
&redirect("");