From 30e9932c6ad14849bab5618fd1ca42d607999325 Mon Sep 17 00:00:00 2001 From: tokul Date: Fri, 26 Dec 2003 09:13:37 +0000 Subject: [PATCH] 1. added non anonymous ldap binding patch. (thanks to Ilyak Kasnacheev ) 2. added ldap protocol version binding. (bug no. 829929) 3. cleaned administrator plugin options 4. added global sql address book support. Obsolates MySQL address book plugin (http://www.squirrelmail.org/plugin_view.php?id=104). git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@6323 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- config/conf.pl | 192 +++++++++++++++++++++++++++++- config/config_default.php | 8 +- functions/abook_database.php | 11 +- functions/abook_ldap_server.php | 51 ++++++-- functions/addressbook.php | 25 +++- plugins/administrator/defines.php | 34 ++++-- 6 files changed, 292 insertions(+), 29 deletions(-) diff --git a/config/conf.pl b/config/conf.pl index f2cd4071..c9ccec0d 100755 --- a/config/conf.pl +++ b/config/conf.pl @@ -230,6 +230,21 @@ while ( $line = ) { $tmp =~ s/[\'|\"],?\s*$//; $tmp =~ s/[\'|\"]\);\s*$//; $name = $tmp; + } elsif ( $tmp =~ /^\s*[\'|\"]binddn[\'|\"]/i ) { + $tmp =~ s/^\s*[\'|\"]binddn[\'|\"]\s*=>\s*[\'|\"]//i; + $tmp =~ s/[\'|\"],?\s*$//; + $tmp =~ s/[\'|\"]\);\s*$//; + $binddn = $tmp; + } elsif ( $tmp =~ /^\s*[\'|\"]bindpw[\'|\"]/i ) { + $tmp =~ s/^\s*[\'|\"]bindpw[\'|\"]\s*=>\s*[\'|\"]//i; + $tmp =~ s/[\'|\"],?\s*$//; + $tmp =~ s/[\'|\"]\);\s*$//; + $bindpw = $tmp; + } elsif ( $tmp =~ /^\s*[\'|\"]protocol[\'|\"]/i ) { + $tmp =~ s/^\s*[\'|\"]protocol[\'|\"]\s*=>\s*[\'|\"]?//i; + $tmp =~ s/[\'|\"]?,?\s*$//; + $tmp =~ s/[\'|\"]?\);\s*$//; + $protocol = $tmp; } } $ldap_host[$sub] = $host; @@ -238,6 +253,9 @@ while ( $line = ) { $ldap_port[$sub] = $port; $ldap_maxrows[$sub] = $maxrows; $ldap_charset[$sub] = $charset; + $ldap_binddn[$sub] = $binddn; + $ldap_bindpw[$sub] = $bindpw; + $ldap_protocol[$sub] = $protocol; } elsif ( $options[0] =~ /^(data_dir|attachment_dir|theme_css|org_logo|signout_page)$/ ) { ${ $options[0] } = &change_to_rel_path($options[1]); } else { @@ -327,6 +345,15 @@ if ( !$prefs_user_field ) { if ( !$prefs_key_field ) { $prefs_key_field = 'prefkey'; } +if ( !$addrbook_global_table ) { + $addrbook_global_table = 'global_abook'; +} +if ( !$addrbook_global_writeable ) { + $addrbook_global_writeable = 'false'; +} +if ( !$addrbook_global_listing ) { + $addrbook_global_listing = 'false'; +} if ( !$prefs_val_field ) { $prefs_val_field = 'prefval'; } @@ -622,6 +649,11 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) ) { print "6. Field for prefs key : $WHT$prefs_key_field$NRM\n"; print "7. Field for prefs value : $WHT$prefs_val_field$NRM\n"; print "\n"; + print "8. DSN for Global Address Book : $WHT$addrbook_global_dsn$NRM\n"; + print "9. Table for Global Address Book : $WHT$addrbook_global_table$NRM\n"; + print "10. Allow writing into Global Address Book : $WHT$addrbook_global_writeable$NRM\n"; + print "11. Allow listing of Global Address Book : $WHT$addrbook_global_listing$NRM\n"; + print "\n"; print "R Return to Main Menu\n"; } elsif ( $menu == 10 ) { print $WHT. "Language settings\n" . $NRM; @@ -777,6 +809,10 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) ) { elsif ( $command == 5 ) { $prefs_user_field = command95(); } elsif ( $command == 6 ) { $prefs_key_field = command96(); } elsif ( $command == 7 ) { $prefs_val_field = command97(); } + elsif ( $command == 8 ) { $addrbook_global_dsn = command98(); } + elsif ( $command == 9 ) { $addrbook_global_table = command99(); } + elsif ( $command == 10 ) { $addrbook_global_writeable = command910(); } + elsif ( $command == 11 ) { $addrbook_global_listing = command911(); } } elsif ( $menu == 10 ) { if ( $command == 1 ) { $squirrelmail_default_language = commandA1(); } elsif ( $command == 2 ) { $default_charset = commandA2(); } @@ -1882,7 +1918,7 @@ sub command33a { print " Relative: ../data/\n"; print "Relative paths to directories outside of the SquirrelMail distribution\n"; print "will be converted to their absolute path equivalents in config.php.\n\n"; - print "Note: There are potential security risks with having a writable directory\n"; + print "Note: There are potential security risks with having a writeable directory\n"; print "under the web server's root directory (ex: /home/httpd/html).\n"; print "For this reason, it is recommended to put the data directory\n"; print "in an alternate location of your choice. \n"; @@ -2405,6 +2441,16 @@ sub command61 { if ( $ldap_maxrows[$count] ) { print " maxrows: $ldap_maxrows[$count]\n"; } + if ( $ldap_binddn[$count] ) { + print " binddn: $ldap_binddn[$count]\n"; + if ( $ldap_bindpw[$count] ) { + print " bindpw: $ldap_bindpw[$count]\n"; + } + } + if ( $ldap_protocol[$count] ) { + print " protocol: $ldap_protocol[$count]\n"; + } + print "\n"; $count++; } @@ -2466,6 +2512,36 @@ sub command61 { print "\n"; + print "If your LDAP server does not like anonymous logins, you can specify bind DN.\n"; + print "Default is none, anonymous bind. Press ENTER for default.\n"; + print "binddn: "; + $name = ; + $name =~ s/[\r|\n]//g; + $ldap_binddn[$sub] = $name; + + print "\n"; + + if ( $ldap_binddn[$sub] ne '' ) { + + print "Now, please specify password for that DN.\n"; + print "bindpw: "; + $name = ; + $name =~ s/[\r|\n]//g; + $ldap_bindpw[$sub] = $name; + + print "\n"; + } + + print "You can specify bind protocol version here.\n"; + print "Default protocol version depends on your php ldap settings.\n"; + print "Press ENTER for default.\n"; + print "protocol: "; + $name = ; + $name =~ s/[\r|\n]//g; + $ldap_protocol[$sub] = $name; + + print "\n"; + } elsif ( $input =~ /^\s*-\s*[0-9]?/ ) { if ( $input =~ /[0-9]+\s*$/ ) { $rem_num = $input; @@ -2481,6 +2557,9 @@ sub command61 { @new_ldap_name = (); @new_ldap_charset = (); @new_ldap_maxrows = (); + @new_ldap_bindpw = (); + @new_ldap_binddn = (); + @new_ldap_protocol = (); while ( $count <= $#ldap_host ) { if ( $count != $rem_num ) { @@ -2490,6 +2569,9 @@ sub command61 { @new_ldap_name = ( @new_ldap_name, $ldap_name[$count] ); @new_ldap_charset = ( @new_ldap_charset, $ldap_charset[$count] ); @new_ldap_maxrows = ( @new_ldap_maxrows, $ldap_maxrows[$count] ); + @new_ldap_binddn = ( @new_ldap_binddn, $ldap_binddn[$count] ); + @new_ldap_bindpw = ( @new_ldap_bindpw, $ldap_bindpw[$count] ); + @new_ldap_protocol = ( @new_ldap_protocol, $ldap_protocol[$count] ); } $count++; } @@ -2499,6 +2581,10 @@ sub command61 { @ldap_name = @new_ldap_name; @ldap_charset = @new_ldap_charset; @ldap_maxrows = @new_ldap_maxrows; + @ldap_binddn = @new_ldap_binddn; + @ldap_bindpw = @new_ldap_bindpw; + @ldap_protocol = @new_ldap_protocol; + } elsif ( $input =~ /^\s*\?\s*/ ) { print ".-------------------------.\n"; print "| + (add host) |\n"; @@ -2664,6 +2750,85 @@ sub command97 { return $new_field; } +sub command98 { + print "If you want to store your global address book in a database then\n"; + print "you need to set this DSN to a valid value. The format for this is:\n"; + print "mysql://user:pass\@hostname/dbname\n"; + print "Where mysql can be one of the databases PHP supports, the most common\n"; + print "of these are mysql, msql and pgsql\n"; + print "If the DSN is left empty (hit space and then return) the database\n"; + print "related code for global SQL address book will not be used\n"; + print "\n"; + + if ( $addrbook_global_dsn eq "" ) { + $default_value = "Disabled"; + } else { + $default_value = $addrbook_global_dsn; + } + print "[$WHT$addrbook_global_dsn$NRM]: $WHT"; + $new_dsn = ; + if ( $new_dsn eq "\n" ) { + $new_dsn = ""; + } else { + $new_dsn =~ s/[\r|\n]//g; + $new_dsn =~ s/^\s+$//g; + } + return $new_dsn; +} + +sub command99 { + print "This is the name of the table you want to store the global address book\n"; + print "data in, it defaults to 'global_address'\n"; + print "\n"; + print "[$WHT$addrbook_global_table$NRM]: $WHT"; + $new_table = ; + if ( $new_table eq "\n" ) { + $new_table = $addrbook_global_table; + } else { + $new_table =~ s/[\r|\n]//g; + } + return $new_table; +} + +sub command910 { + print "This option controls users\' ability to add or modify records stored \n"; + print "in global address book\n"; + + if ( lc($addrbook_global_writeable) eq "true" ) { + $default_value = "y"; + } else { + $default_value = "n"; + } + print "Allow writing into global address book? (y/n) [$WHT$default_value$NRM]: $WHT"; + $addrbook_global_writeable = ; + if ( ( $addrbook_global_writeable =~ /^y\n/i ) || ( ( $addrbook_global_writeable =~ /^\n/ ) && ( $default_value eq "y" ) ) ) { + $addrbook_global_writeable = "true"; + } else { + $addrbook_global_writeable = "false"; + } + return $addrbook_global_writeable; +} + +sub command911 { + print "Enable this option if you want to see listing of addresses stored \n"; + print "in global address book\n"; + + if ( lc($addrbook_global_listing) eq "true" ) { + $default_value = "y"; + } else { + $default_value = "n"; + } + print "Allow listing of global address book? (y/n) [$WHT$default_value$NRM]: $WHT"; + $addrbook_global_listing = ; + if ( ( $addrbook_global_listing =~ /^y\n/i ) || ( ( $addrbook_global_listing =~ /^\n/ ) && ( $default_value eq "y" ) ) ) { + $addrbook_global_listing = "true"; + } else { + $addrbook_global_listing = "false"; + } + return $addrbook_global_listing; +} + + # Default language sub commandA1 { print "SquirrelMail attempts to set the language in many ways. If it\n"; @@ -3070,6 +3235,21 @@ sub save_data { # integer print CF " 'maxrows' => $ldap_maxrows[$count]"; } + if ( $ldap_binddn[$count] ) { + print CF ",\n"; + # string + print CF " 'binddn' => '$ldap_binddn[$count]'"; + if ( $ldap_bindpw[$count] ) { + print CF ",\n"; + # string + print CF " 'bindpw' => '$ldap_bindpw[$count]'"; + } + } + if ( $ldap_protocol[$count] ) { + print CF ",\n"; + # integer + print CF " 'protocol' => $ldap_protocol[$count]"; + } print CF "\n"; print CF ");\n"; print CF "\n"; @@ -3088,7 +3268,15 @@ sub save_data { # string print CF "\$prefs_key_field = '$prefs_key_field';\n"; # string - print CF "\$prefs_val_field = '$prefs_val_field';\n"; + print CF "\$prefs_val_field = '$prefs_val_field';\n\n"; + # string + print CF "\$addrbook_global_dsn = '$addrbook_global_dsn';\n"; + # string + print CF "\$addrbook_global_table = '$addrbook_global_table';\n"; + # boolean + print CF "\$addrbook_global_writeable = $addrbook_global_writeable;\n\n"; + # boolean + print CF "\$addrbook_global_listing = $addrbook_global_listing;\n\n"; # boolean print CF "\$no_list_for_subscribe = $no_list_for_subscribe;\n"; diff --git a/config/config_default.php b/config/config_default.php index 4df677ab..581130c1 100644 --- a/config/config_default.php +++ b/config/config_default.php @@ -588,7 +588,13 @@ $prefs_table = 'userprefs'; $prefs_key_field = 'prefkey'; $prefs_user_field = 'user'; $prefs_val_field = 'prefval'; - +/** + * Global sql database options + */ +$addrbook_global_dsn = ''; +$addrbook_global_table = 'global_abook'; +$addrbook_global_writeable = false; +$addrbook_global_listing = false; /*** Language settings ***/ /** diff --git a/functions/abook_database.php b/functions/abook_database.php index 0a2b09b6..8023f704 100644 --- a/functions/abook_database.php +++ b/functions/abook_database.php @@ -74,6 +74,10 @@ class abook_database extends addressbook_backend { $this->writeable = $param['writeable']; } + if (isset($param['listing'])) { + $this->listing = $param['listing']; + } + $this->open(true); } else { @@ -121,7 +125,7 @@ class abook_database extends addressbook_backend { if(!$this->open()) { return false; } - + /* To be replaced by advanded search expression parsing */ if (is_array($expr)) { return; @@ -197,6 +201,11 @@ class abook_database extends addressbook_backend { if (!$this->open()) { return false; } + + if(!$this->listing) { + return array(); + } + $query = sprintf("SELECT * FROM %s WHERE owner='%s'", $this->table, $this->owner); diff --git a/functions/abook_ldap_server.php b/functions/abook_ldap_server.php index 98383918..858889a1 100644 --- a/functions/abook_ldap_server.php +++ b/functions/abook_ldap_server.php @@ -20,6 +20,9 @@ * ? maxrows => Maximum # of rows in search result * ? timeout => Timeout for LDAP operations (in seconds, default: 30) * Might not work for all LDAP libraries or servers. + * ? binddn => LDAP Bind DN. + * ? bindpw => LDAP Bind Password. + * ? protocol => LDAP Bind protocol. * * NOTE. This class should not be used directly. Use the * "AddressBook" class instead. @@ -46,6 +49,9 @@ class abook_ldap_server extends addressbook_backend { var $bound = false; /* True if LDAP server is bound */ var $maxrows = 250; /* Max rows in result */ var $timeout = 30; /* Timeout for LDAP operations (in seconds) */ + var $binddn = ''; /* DN to bind to (non-anonymous bind) */ + var $bindpw = ''; /* password to bind with (non-anonymous bind) */ + var $protocol = ''; /* protocol used to connect to ldap server */ /* Constructor. Connects to database */ function abook_ldap_server($param) { @@ -68,6 +74,15 @@ class abook_ldap_server extends addressbook_backend { if(isset($param['timeout'])) { $this->timeout = $param['timeout']; } + if(isset($param['binddn'])) { + $this->binddn = $param['binddn']; + } + if(isset($param['bindpw'])) { + $this->bindpw = $param['bindpw']; + } + if(isset($param['protocol'])) { + $this->protocol = $param['protocol']; + } if(empty($param['name'])) { $this->sname = 'LDAP: ' . $param['host']; } @@ -99,15 +114,35 @@ class abook_ldap_server extends addressbook_backend { return $this->set_error('ldap_connect failed'); } } - - if(!@ldap_bind($this->linkid)) { - if(function_exists('ldap_error')) { - return $this->set_error(ldap_error($this->linkid)); - } else { - return $this->set_error('ldap_bind failed'); - } + + if(!empty($this->protocol)) { + if(!@ldap_set_option($this->linkid, LDAP_OPT_PROTOCOL_VERSION, $this->protocol)) { + if(function_exists('ldap_error')) { + return $this->set_error(ldap_error($this->linkid)); + } else { + return $this->set_error('ldap_set_option failed'); + } + } + } + + if(!empty($this->binddn)) { + if(!@ldap_bind($this->linkid, $this->binddn, $this->bindpw)) { + if(function_exists('ldap_error')) { + return $this->set_error(ldap_error($this->linkid)); + } else { + return $this->set_error('authenticated ldap_bind failed'); + } + } + } else { + if(!@ldap_bind($this->linkid)) { + if(function_exists('ldap_error')) { + return $this->set_error(ldap_error($this->linkid)); + } else { + return $this->set_error('anonymous ldap_bind failed'); + } + } } - + $this->bound = true; return true; diff --git a/functions/addressbook.php b/functions/addressbook.php index ccef5508..57152cbf 100644 --- a/functions/addressbook.php +++ b/functions/addressbook.php @@ -30,7 +30,7 @@ */ -global $addrbook_dsn; +global $addrbook_dsn, $addrbook_global_dsn; /** Create and initialize an addressbook object. @@ -39,6 +39,7 @@ global $addrbook_dsn; function addressbook_init($showerr = true, $onlylocal = false) { global $data_dir, $username, $ldap_server, $address_book_global_filename; global $addrbook_dsn, $addrbook_table; + global $addrbook_global_dsn, $addrbook_global_table, $addrbook_global_writeable, $addrbook_global_listing; /* Create a new addressbook object */ $abook = new AddressBook; @@ -81,6 +82,21 @@ function addressbook_init($showerr = true, $onlylocal = false) { } } + /* Load global addressbook from SQL if configured */ + if (isset($addrbook_global_dsn) && !empty($addrbook_global_dsn)) { + /* Database configured */ + if (!isset($addrbook_global_table) || empty($addrbook_global_table)) { + $addrbook_global_table = 'global_abook'; + } + $r = $abook->add_backend('database', + Array('dsn' => $addrbook_global_dsn, + 'owner' => 'global', + 'name' => _("Global address book"), + 'writeable' => $addrbook_global_writeable, + 'listing' => $addrbook_global_listing, + 'table' => $addrbook_global_table)); + } + if ($onlylocal) { return $abook; } @@ -388,7 +404,7 @@ class AddressBook { $alias = array(0 => $alias); } - /* Check that specified backend is writable */ + /* Check that specified backend is writeable */ if (!$this->backends[$bnum]->writeable) { $this->error = _("Addressbook is read-only"); return false; @@ -441,7 +457,7 @@ class AddressBook { $userdata['nickname'] = $userdata['email']; } - /* Check that specified backend is writable */ + /* Check that specified backend is writeable */ if (!$this->backends[$bnum]->writeable) { $this->error = _("Addressbook is read-only");; return false; @@ -548,7 +564,8 @@ if (isset($address_book_global_filename)) { } /* Only load database backend if database is configured */ -if(isset($addrbook_dsn) && !empty($addrbook_dsn)) { +if((isset($addrbook_dsn) && !empty($addrbook_dsn)) || + (isset($addrbook_global_dsn) && !empty($addrbook_global_dsn)) ) { include_once(SM_PATH . 'functions/abook_database.php'); } diff --git a/plugins/administrator/defines.php b/plugins/administrator/defines.php index 3d7dae32..7776f845 100644 --- a/plugins/administrator/defines.php +++ b/plugins/administrator/defines.php @@ -243,9 +243,6 @@ $defcfg = array( '$config_version' => array( 'name' => _("Config File Version"), '$allow_charset_search' => array( 'name' => _("Allow server charset search"), 'type' => SMOPT_TYPE_BOOLEAN, 'default' => false ), - '$uid_support' => array( 'name' => _("UID support"), - 'type' => SMOPT_TYPE_BOOLEAN, - 'default' => false ), '$session_name' => array( 'name' => _("PHP session name"), 'type' => SMOPT_TYPE_HIDDEN ), /* --------------------------------------------------------*/ @@ -283,16 +280,17 @@ $defcfg = array( '$config_version' => array( 'name' => _("Config File Version"), 'type' => SMOPT_TYPE_STRING, 'size' => 40, 'default' => 'prefval' ), - /* --------------------------------------------------------*/ - 'Group7' => array( 'name' => _("Themes"), - 'type' => SMOPT_TYPE_TITLE ), - '$theme_css' => array( 'name' => _("Style Sheet URL (css)"), - 'type' => SMOPT_TYPE_PATH, - 'size' => 40 ), - '$theme_default' => array( 'name' => _("Default theme"), - 'type' => SMOPT_TYPE_INTEGER, - 'default' => 0, - 'comment' => _("Use index number of theme") ), + '$addrbook_global_dsn' => array( 'name' => _("Global address book DSN"), + 'type' => SMOPT_TYPE_STRING, + 'size' => 40 ), + '$addrbook_global_table' => array( 'name' => _("Global address book table"), + 'type' => SMOPT_TYPE_STRING, + 'size' => 40, + 'default' => 'global_abook' ), + '$addrbook_global_writable' => array( 'name' => _("Allow writing into global address book"), + 'type' => SMOPT_TYPE_BOOLEAN ), + '$addrbook_global_listing' => array( 'name' => _("Allow listing of global address book"), + 'type' => SMOPT_TYPE_BOOLEAN ), 'Group9' => array( 'name' => _("Language settings"), 'type' => SMOPT_TYPE_TITLE ), '$squirrelmail_default_language' => array( 'name' => _("Default Language"), @@ -330,6 +328,16 @@ $defcfg = array( '$config_version' => array( 'name' => _("Config File Version"), '$use_php_iconv' => array( 'name' => _("Use php iconv functions"), 'type' => SMOPT_TYPE_BOOLEAN ), /* --------------------------------------------------------*/ + 'Group7' => array( 'name' => _("Themes"), + 'type' => SMOPT_TYPE_TITLE ), + '$theme_css' => array( 'name' => _("Style Sheet URL (css)"), + 'type' => SMOPT_TYPE_PATH, + 'size' => 40 ), + '$theme_default' => array( 'name' => _("Default theme"), + 'type' => SMOPT_TYPE_INTEGER, + 'default' => 0, + 'comment' => _("Use index number of theme") ), + /* --------------------------------------------------------*/ '$config_use_color' => array( 'name' => '', 'type' => SMOPT_TYPE_HIDDEN ), '$no_list_for_subscribe' => array( 'name' => '', -- 2.25.1