Use generic LDAP client function
authorJamie Cameron <jcameron@webmin.com>
Thu, 4 Dec 2008 23:02:27 +0000 (23:02 +0000)
committerJamie Cameron <jcameron@webmin.com>
Thu, 4 Dec 2008 23:02:27 +0000 (23:02 +0000)
ldap-client/ldap-client-lib.pl
ldap-useradmin/config.info
ldap-useradmin/index.cgi
ldap-useradmin/lang/en
ldap-useradmin/ldap-useradmin-lib.pl
ldap-useradmin/module.info

index d9921eb..0bf975d 100644 (file)
@@ -177,7 +177,7 @@ if ($@) {
        return &text('ldap_emodule2', "<tt>Net::LDAP</tt>");
        }
 if (!-r $config{'auth_ldap'}) {
-       $ldap_hosts && $ldap_user && $ldap_pass ||
+       $ldap_hosts && $ldap_user ||
                return &text('ldap_econf', "<tt>$config{'auth_ldap'}</tt>");
        }
 
@@ -188,7 +188,7 @@ local ($ldap, $use_ssl, $err);
 local $ssl = &find_svalue("ssl", $conf);
 if ($ldap_hosts) {
        # Using hosts from parameter
-       local @hosts = split(/\s+/, $ldap_hosts);
+       local @hosts = split(/[ \t,]+/, $ldap_hosts);
        if ($ldap_ssl ne '') {
                $use_ssl = $ldap_ssl;
                }
index bcd9b18..51f2699 100644 (file)
@@ -1,5 +1,4 @@
 line1=LDAP server options,11
-auth_ldap=Linux LDAP NSS library config file,3,None (use settings below),40,,,Use settings from file
 ldap_host=LDAP server host,3,From NSS config file
 ldap_port=LDAP server port,3,From NSS config file or default
 ldap_tls=LDAP server uses encryption?,1,1-Yes SSL,2-Yes TLS,0-No
index 6361c14..61eba9a 100755 (executable)
@@ -7,35 +7,6 @@ require './ldap-useradmin-lib.pl';
 &useradmin::load_theme_library();      # So that ui functions work
 &ReadParse();
 
-# Make sure the LDAP NSS client config file exists, or the needed information
-# has been provided
-if ($config{'auth_ldap'}) {
-       if (!-r $config{'auth_ldap'}) {
-               print &text('index_econfig',
-                   "<tt>$config{'auth_ldap'}</tt>",
-                   "$gconfig{'webprefix'}/config.cgi?$module_name"),"<p>\n";
-               &ui_print_footer("/", $text{'index'});
-               exit;
-               }
-       $nss = &get_nss_config();
-       if ($nss->{'pidfile'} || $nss->{'directory'}) {
-               print &text('index_econfig2',
-                   "<tt>$config{'auth_ldap'}</tt>",
-                   "$gconfig{'webprefix'}/config.cgi?$module_name"),"<p>\n";
-               &ui_print_footer("/", $text{'index'});
-               exit;
-               }
-       }
-else {
-       if (!$config{'ldap_host'} || !$config{'login'} || !$config{'pass'} ||
-           !$config{'user_base'} || !$config{'group_base'}) {
-               print &text('index_ehost',
-                   "$gconfig{'webprefix'}/config.cgi?$module_name"),"<p>\n";
-               &ui_print_footer("/", $text{'index'});
-               exit;
-               }
-       }
-
 # Make sure the LDAP Perl module is installed, and if not offer to install
 if (!$got_net_ldap) {
        local @needs;
@@ -71,6 +42,14 @@ if (!$schema) {
        exit;
        }
 
+# Make sure the LDAP bases are set or available
+if (!&get_user_base() || !&get_group_base()) {
+       print &text('index_ebase',
+                   "$gconfig{'webprefix'}/config.cgi?$module_name"),"<p>\n";
+       &ui_print_footer("/", $text{'index'});
+       exit;
+       }
+
 if ($config{'imap_host'}) {
        # Make sure the IMAP Perl module is installed, and if not offer
        # to install
index d600478..cb99352 100644 (file)
@@ -1,10 +1,8 @@
 index_title=LDAP Users and Groups
-index_econfig=The LDAP NSS configuration file $1 was not found on your system. You will need to adjust the <a href='$2'>module configuration</a> to use the correct path.
-index_econfig2=The LDAP NSS configuration file $1 appears to be the LDAP <i>server</i> configuration file. You will need to adjust the <a href='$2'>module configuration</a> to use the path to the NSS <i>client</i> config file.
-index_ehost=If no LDAP NSS configuration file is set in the <a href='$1'>module configuration</a>, an LDAP server, login, password, base user DN and base group DN must be set instead.
+index_ebase=No LDAP client configuration file was found on your system, so the use and group bases must be set on the <a href='$1'>module config</a> page.
 index_eperl=The $1 Perl module that this module requires is not installed or is not working properly. <a href='$2'>Click here</a> to have it downloaded and installed now.
 index_eperl2=The error reported by Perl when trying to load the module was :
-index_eldap=$1. Maybe your <a href='$2'>module configuration</a> is incorrect.
+index_eldap=$1. Click here to adjust the <a href='$2'>module configuration</a>.
 index_eschema=Webmin has connected to the LDAP server, but failed to fetch the schema. Make sure that access has not been denied in the <a href='$1'>LDAP Server</a> module.
 index_eimap=$1. Maybe your <a href='$2'>module configuration</a> is incorrect.
 index_emd5=This module has been <a href='$1'>configured</a> to use MD5 encryption for passwords, but the $2 Perl module is not installed. <a href='$3'>Click here</a> to have the $2 module downloaded and installed.
@@ -27,6 +25,8 @@ conn_essl=Failed to start SSL for LDAP server $1 port $2 : $3
 conn_elogin=Failed to bind to LDAP server $1 as $2 : $3
 imap_econn=Failed to connect to IMAP server $1
 imap_elogin=Failed to login to IMAP server $1 as $2 : $3
+conn_eldap_host=No LDAP client configuration file was found on your system, so the LDAP server must be set on the Module Config page
+conn_elogin=No LDAP client configuration file was found on your system, so the LDAP login must be set on the Module Config page
 
 uedit_cap=User capabilities
 uedit_samba=Samba login?
index 88df752..9aaaaac 100644 (file)
@@ -7,6 +7,7 @@ do '../web-lib.pl';
 &init_config();
 do '../ui-lib.pl';
 &foreign_require("useradmin", "user-lib.pl");
+&foreign_require("ldap-client", "ldap-client-lib.pl");
 %access = &get_module_acl();
 $useradmin::access{'udelete'} = 1;     # needed for users_table / groups_table
 $useradmin::access{'gdelete'} = 1;
@@ -49,139 +50,36 @@ $match_modes = [ [ 0, $text{'index_equals'} ], [ 1, $text{'index_contains'} ],
                  [ 2, $text{'index_nequals'} ], [ 3, $text{'index_ncontains'} ],
                 [ 6, $text{'index_lower'} ], [ 7, $text{'index_higher'} ] ];
 
-# get_nss_config()
-# Parses the NSS config file into a hash reference
-sub get_nss_config
-{
-return undef if (!$config{'auth_ldap'});
-if (!%nss_config_cache) {
-       open(CONF, $config{'auth_ldap'});
-       while(<CONF>) {
-               s/\r|\n//g;
-               s/#.*$//;
-               if (/^\s*(\S+)\s*(.*)/) {
-                       $nss_config_cache{lc($1)} = $2;
-                       }
-               }
-       close(CONF);
-       }
-return \%nss_config_cache;
-}
-
 # ldap_connect(return-error)
 # Connect to the LDAP server and return a handle to the Net::LDAP object
 sub ldap_connect
 {
-local $conf = &get_nss_config();
-
-# Work out LDAP hostnames, ports and SSL
-local (@hosts, $port);
-if ($conf) {
-       # From ldap.conf file, using host and uri lines
-       my @hostnames = split(/[ ,]+/, $conf->{'host'});
-       my $port = $conf->{'port'};
-       my @uris = split(/[ ,]+/, $conf->{'uri'});
-       my $ssl = $conf->{'ssl'};
-       foreach my $hname (@hostnames) {
-               push(@hosts, [ $hname, $port, $ssl eq 'start_tls' ? 2 :
-                                             $ssl eq 'on' ? 1 : 0 ]);
-               }
-       foreach my $u (@uris) {
-               if ($u =~ /^(ldap|ldaps|ldapi):\/\/([a-z0-9\_\-\.]+)(:(\d+))?/){
-                       my ($proto, $host, $port) = ($1, $2, $4);
-                       if (!$port && $proto eq "ldap") {
-                               $port = 389;
-                               }
-                       elsif (!$port && $proto eq "ldaps") {
-                               $port = 636;
-                               }
-                       push(@hosts, [ $host, $port,
-                                      $proto eq 'ldaps' ? 1 : 0 ]);
+if (!$ldap_client::config{'auth_ldap'} ||
+    !-r $ldap_client::config{'auth_ldap'}) {
+       # LDAP client config file not known .. force manual specification
+       foreach my $f ("ldap_host", "login") {
+               if (!$config{$f}) {
+                       if ($_[0]) { return $text{'conn_e'.$f}; }
+                       else { &error($text{'conn_e'.$f}); }
                        }
                }
        }
-else {
-       # From module config
-       foreach my $hname (split(/[ ,]+/, $config{'ldap_host'})) {
-               push(@hosts, [ $hname, $config{'ldap_port'},
-                              $config{'ldap_tls'} ]);
-               }
-       }
-if (!@hosts) {
-       # Last-ditch fallback
-       push(@hosts, [ "localhost", 389, 0 ]);
-       }
-
-# Try each host in turn
-local ($ldap, $err);
-foreach my $host (@hosts) {
-       $ldap = Net::LDAP->new($host->[0], port => $host->[1],
-                              scheme => $host->[2] == 1 ? 'ldaps' : 'ldap');
-       if (!$ldap) {
-               $err = &text('conn_econn',
-                            "<tt>$host->[0]</tt>","<tt>$host->[1]</tt>");
-               next;
-               }
-       # Switch to TLS if needed
-       if ($host->[2] == 2) {
-               my $mesg;
-               eval { $mesg = $ldap->start_tls(); };
-                if ($@ || !$mesg || $mesg->code) {
-                        # TLS failed
-                        $err = &text('conn_essl',
-                             "<tt>$host->[0]</tt>", "<tt>$host->[1]</tt>", $@);
-                        next;
-                        }
-               }
-       # If we got here, it all worked!
-       $err = undef;
-       last;
-       }
-if ($err) {
-       if ($_[0]) { return $err; }
-       else { &error($err); }
-       }
 
-local ($dn, $password);
-if ($config{'login'}) {
-       # Use the configured login
-       $dn = $config{'login'};
-       $password = $config{'pass'};
-       }
-elsif ($conf->{'rootbinddn'}) {
-       # Use the root login if we have one
-       $dn = $conf->{'rootbinddn'};
-       open(SECRET, $secret_file);
-       $password = <SECRET>;
-       $password =~ s/\r|\n//g;
-       close(SECRET);
-       }
-else {
-       # Use the normal login
-       $dn = $conf->{'binddn'};
-       $password = $conf->{'bindpw'};
-       }
-local $mesg;
-if ($dn) {
-       $mesg = $ldap->bind(dn => $dn, password => $password);
-       }
-else {
-       $mesg = $ldap->bind(anonymous => 1);
-       }
-if (!$mesg || $mesg->code) {
-       local $err = &text('conn_elogin', "<tt>$conf{'host'}</tt>",
-                    $dn, $mesg ? $mesg->error : "Unknown error");
-       if ($_[0]) { return $err; }
-       else { &error($err); }
-       }
-return $ldap;
+local $ldap = &ldap_client::generic_ldap_connect(
+               $config{'ldap_host'}, $config{'ldap_port'},
+               $config{'ldap_tls'}, $config{'login'}, $config{'pass'});
+if (ref($ldap)) { return $ldap; }
+elsif ($_[0]) { return $ldap; }
+else { &error($ldap); }
 }
 
 # get_user_base()
 sub get_user_base
 {
-local $conf = &get_nss_config();
-local $base = $config{'user_base'} || $conf->{'nss_base_passwd'} || $conf->{'base'};
+local $conf = &ldap_client::get_config();
+local $base = $config{'user_base'} ||
+             &ldap_client::find_svalue("nss_base_passwd", $conf) ||
+             &ldap_client::find_svalue("base", $conf);
 $base =~ s/\?.*$//;
 return $base;
 }
@@ -189,8 +87,10 @@ return $base;
 # get_group_base()
 sub get_group_base
 {
-local $conf = &get_nss_config();
-local $base = $config{'group_base'} || $conf->{'nss_base_group'} || $conf->{'base'};
+local $conf = &ldap_client::get_config();
+local $base = $config{'group_base'} ||
+             &ldap_client::find_svalue("nss_base_group", $conf) ||
+             &ldap_client::find_svalue("base", $conf);
 $base =~ s/\?.*$//;
 return $base;
 }
index 4484235..857afb6 100644 (file)
@@ -1,6 +1,6 @@
 desc=LDAP Users and Groups
 category=system
-depends=useradmin
+depends=useradmin ldap-client
 longdesc=Manage users and groups stored in an LDAP database, used for Unix, Samba and Cyrus IMAP authentication.
 desc_ca=Usuaris i Grups LDAP
 desc_de=LDAP Nutzer und Gruppen