Yet more work on LDAP and LDIF
authorJamie Cameron <jcameron@webmin.com>
Tue, 5 May 2009 01:16:34 +0000 (01:16 +0000)
committerJamie Cameron <jcameron@webmin.com>
Tue, 5 May 2009 01:16:34 +0000 (01:16 +0000)
14 files changed:
ldap-server/acl_save.cgi
ldap-server/config-Ubuntu-Linux-8.10-*
ldap-server/delete_acls.cgi
ldap-server/down_acl.cgi
ldap-server/down_schema.cgi
ldap-server/gencert.cgi
ldap-server/gencert_form.cgi
ldap-server/gencert_ldif.cgi [new file with mode: 0755]
ldap-server/ldap-server-lib.pl
ldap-server/save_ldif.cgi [new file with mode: 0755]
ldap-server/save_schema.cgi
ldap-server/save_slapd.cgi
ldap-server/up_acl.cgi
ldap-server/up_schema.cgi

index a410df4..b45e712 100644 (file)
@@ -8,7 +8,7 @@ $access{'acl'} || &error($text{'acl_ecannot'});
 &ReadParse();
 
 # Get the current rule
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 @access = &find("access", $conf);
 if (!$in{'new'}) {
@@ -85,7 +85,7 @@ else {
 # Write out access directives
 &save_directive($conf, "access", @access);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 # Log and return
 &webmin_log($in{'delete'} ? "delete" : $in{'new'} ? "create" : "modify",
index 1c5f04a..af45b09 100644 (file)
@@ -1,7 +1,7 @@
 config_file=/etc/ldap/slapd.d
 schema_dir=/etc/ldap/slapd.d/cn=config/cn=schema
 slapd=slapd
-ldap_user=ldap
+ldap_user=openldap
 browse_max=100
 start_cmd=/etc/init.d/slapd start
 stop_cmd=/etc/init.d/slapd stop
index f95c87e..6bc122d 100644 (file)
@@ -8,7 +8,7 @@ $access{'acl'} || &error($text{'acl_ecannot'});
 &ReadParse();
 
 # Filter out un-wanted rules
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 @access = &find("access", $conf);
 %d = map { $_, 1 } split(/\0/, $in{'d'});
@@ -20,7 +20,7 @@ for($i=0; $i<@access; $i++) {
 # Save them
 &save_directive($conf, "access", @newaccess);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("delete", "accesses", scalar(keys(%d)));
 &redirect("edit_acl.cgi");
index e3f8e62..fb94ec8 100644 (file)
@@ -7,7 +7,7 @@ $access{'acl'} || &error($text{'acl_ecannot'});
 &ReadParse();
 
 # Find it
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 @access = &find("access", $conf);
 $p = &parse_ldap_access($access[$in{'idx'}]);
@@ -17,7 +17,7 @@ $p = &parse_ldap_access($access[$in{'idx'}]);
        ($access[$in{'idx'}], $access[$in{'idx'}+1]);
 &save_directive($conf, "access", @access);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("down", "access", $p->{'what'});
 &redirect("edit_acl.cgi");
index 3edafe1..f38173a 100644 (file)
@@ -7,7 +7,7 @@ $access{'schema'} || &error($text{'schema_ecannot'});
 &ReadParse();
 
 # Find it includes
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 @incs = &find_value("include", $conf);
 $idx = &indexof($in{'file'}, @incs);
@@ -17,7 +17,7 @@ $idx > 0 || &error($text{'schema_emove'});
 ($incs[$idx+1], $incs[$idx]) = ($incs[$idx], $incs[$idx+1]);
 &save_directive($conf, "include", @incs);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("sup", undef, $in{'file'});
 &redirect("edit_schema.cgi");
index 0a93364..c520daa 100644 (file)
@@ -31,11 +31,11 @@ $err = &webmin::parse_ssl_key_form(\%in, $keyfile,
                           $keyfile, $certfile);
 
 # Update config to use them
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 &save_directive($conf, "TLSCertificateFile", $certfile);
 &save_directive($conf, "TLSCertificateKeyFile", $keyfile);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("gencert");
 &redirect("");
index 39da0ab..04de287 100644 (file)
@@ -9,7 +9,8 @@ $access{'slapd'} || &error($text{'slapd_ecannot'});
 &ui_print_header(undef, $text{'gencert_title'}, "");
 
 print $text{'gencert_desc'},"<p>\n";
-print &ui_form_start("gencert.cgi", "post");
+print &ui_form_start(&get_config_type() == 1 ? "gencert.cgi"
+                                            : "gencert_ldif.cgi", "post");
 print &ui_table_start($text{'gencert_header'}, undef, 2, [ "width=30%" ]);
 
 # Generic key options
@@ -24,7 +25,8 @@ if (&get_config_type() == 1) {
        }
 else {
        $conf = &get_ldif_config();
-       $cert = &find_ldif_value($s->[0], $conf, &get_config_db());
+       $cert = &find_ldif_value(
+               "olcTLSCertificateFile", $conf, &get_config_db());
        }
 if ($cert) {
        print &ui_table_row($text{'gencert_dest'},
diff --git a/ldap-server/gencert_ldif.cgi b/ldap-server/gencert_ldif.cgi
new file mode 100755 (executable)
index 0000000..eb0d32f
--- /dev/null
@@ -0,0 +1,43 @@
+#!/usr/local/bin/perl
+# Actually generate the cert, and update the LDIF format config file
+
+require './ldap-server-lib.pl';
+&local_ldap_server() == 1 || &error($text{'slapd_elocal'});
+$access{'slapd'} || &error($text{'slapd_ecannot'});
+&foreign_require("webmin", "webmin-lib.pl");
+&ReadParse();
+&error_setup($text{'gencert_err'});
+$conf = &get_ldif_config();
+$confdb = &get_config_db();
+
+# Work out dest files
+if ($in{'dest_def'}) {
+       $keyfile = &find_ldif_value("olcTLSCertificateKeyFile", $conf, $confdb);
+       $certfile = &find_ldif_value("olcTLSCertificateFile", $conf, $confdb);
+       }
+else {
+       # In some dir
+       -d $in{'dest'} || &error($text{'gencert_edest'});
+       $keyfile = $in{'dest'}."/ldap.key";
+       $certfile = $in{'dest'}."/ldap.cert";
+       }
+
+# Do it
+$err = &webmin::parse_ssl_key_form(\%in, $keyfile,
+                                  $certfile eq $keyfile ? undef : $certfile);
+&error($err) if ($err);
+
+# Make readable by LDAP user
+&set_ownership_permissions($config{'ldap_user'}, undef, undef,
+                          $keyfile, $certfile);
+
+# Update config to use them
+&lock_slapd_files();
+&save_ldif_directive($conf, "olcTLSCertificateFile", $confdb, $certfile);
+&save_ldif_directive($conf, "olcTLSCertificateKeyFile", $confdb, $keyfile);
+&flush_file_lines();
+&unlock_slapd_files();
+
+&webmin_log("gencert");
+&redirect("");
+
index 9765353..fbf1dfd 100644 (file)
@@ -411,7 +411,49 @@ if (@old) {
        $file = $old[0]->{'file'};
        }
 else {
-       # XXX file for first directive of that class
+       local ($first) = grep { lc($_->{'class'}) eq lc($cls) } @$conf;
+       $first || &error("No LDIF-format config file found for $cls");
+       $file = $first->{'file'};
+       }
+local $lref = &read_file_lines($file);
+for(my $i=0; $i<@old || $i<@values; $i++) {
+       local ($line, @unqvalues, @qvalues, $len);
+       if (defined($values[$i])) {
+               # Work out new line
+               @unqvalues = ref($values[$i]) eq 'ARRAY' ?
+                                @{$values[$i]} :
+                             ref($values[$i]) eq 'HASH' ?
+                                @{$values[$i]->{'values'}} :
+                                ( $values[$i] );
+               $line = $name.": ".join(" ", @unqvalues);
+               }
+       if (defined($old[$i]) && defined($values[$i])) {
+               # Update some directive
+               $lref->[$old[$i]->{'line'}] = $line;
+               if (&indexof($values[$i], @$conf) < 0) {
+                       $old[$i]->{'values'} = \@unqvalues;
+                       }
+               }
+       elsif (defined($old[$i]) && !defined($values[$i])) {
+               # Remove some directive (from cache too)
+               splice(@$lref, $old[$i]->{'line'}, 1);
+               local $idx = &indexof($old[$i], @$conf);
+                splice(@$conf, $idx, 1) if ($idx >= 0);
+               foreach my $c (@$conf) {
+                        if ($c->{'line'} > $old[$i]->{'line'}) {
+                                $c->{'line'} --;
+                                }
+                        }
+               }
+       elsif (!defined($old[$i]) && defined($values[$i])) {
+               # Add some directive
+               local $newdir = { 'name' => $name,
+                                 'line' => scalar(@$lref),
+                                 'file' => $file,
+                                 'values' => \@unqvalues };
+               push(@$lref, $line);
+               push(@$conf, $newdir);
+               }
        }
 }
 
@@ -756,5 +798,30 @@ elsif (&get_config_type() == 2) {
 return undef;
 }
 
+# lock_slapd_files()
+# Lock all LDAP config file(s)
+sub lock_slapd_files
+{
+if (&get_config_type() == 2) {
+       @ldap_lock_files = &recursive_find_ldif($config{'config_file'});
+       }
+else {
+       @ldap_lock_files = ( $config{'config_file'} );
+       }
+foreach my $f (@ldap_lock_files) {
+       &lock_file($f);
+       }
+}
+
+# unlock_slapd_files()
+# Un-lock all LDAP config file(s)
+sub unlock_slapd_files
+{
+foreach my $f (@ldap_lock_files) {
+       &lock_file($f);
+       }
+@ldap_lock_files = ( );
+}
+
 1;
 
diff --git a/ldap-server/save_ldif.cgi b/ldap-server/save_ldif.cgi
new file mode 100755 (executable)
index 0000000..fe8c81e
--- /dev/null
@@ -0,0 +1,94 @@
+#!/usr/local/bin/perl
+# Update local LDAP server LDIF file configuration options
+
+require './ldap-server-lib.pl';
+&error_setup($text{'slapd_err'});
+$access{'slapd'} || &error($text{'slapd_ecannot'});
+&local_ldap_server() == 1 || &error($text{'slapd_elocal'});
+&ReadParse();
+
+&lock_slapd_files();
+$conf = &get_ldif_config();
+
+# Validate and store inputs
+
+# Top-level DN
+$defdb = &get_default_db();
+$in{'suffix'} =~ /=/ || &error($text{'slapd_esuffix'});
+&save_ldif_directive($conf, 'olcSuffix', $defdb, $in{'suffix'});
+
+# Admin login
+$in{'rootdn'} =~ /=/ || &error($text{'slapd_erootdn'});
+&save_ldif_directive($conf, 'olcRootDN', $defdb, $in{'rootdn'});
+
+# Admin password
+if (!$in{'rootchange_def'}) {
+       $in{'rootchange'} =~ /\S/ || &error($text{'slapd_erootpw'});
+       $crypt = &unix_crypt($in{'rootchange'}, substr(time(), -2));
+       &save_ldif_directive($conf, 'olcRootPW', $defdb, "{crypt}".$crypt);
+       $config{'pass'} = $in{'rootchange'};
+       $save_config = 1;
+       }
+
+# Cache sizes
+if (!$in{'dbcachesize_def'}) {
+       $in{'dbcachesize'} =~ /^\d+$/ || &error($text{'slapd_edbcachesize'});
+       &save_ldif_directive($conf, 'olcDbCachesize', $defdb,
+                            $in{'dbcachesize'});
+       }
+else {
+       &save_ldif_directive($conf, 'olcDbCachesize', $defdb, undef);
+       }
+
+# Size limit
+if ($in{'sizelimit_def'}) {
+       &save_ldif_directive($conf, 'olcSizeLimit', $defdb, undef);
+       }
+else {
+       $in{'sizelimit'} =~ /^[1-9]\d*$/ || &error($text{'slapd_esizelimit'});
+       &save_ldif_directive($conf, 'olcSizeLimit', $defdb, $in{'sizelimit'});
+       }
+
+# LDAP protocols
+if (&can_get_ldap_protocols()) {
+       @newprotos = split(/\0/, $in{'protos'});
+       @newprotos || &error($text{'slapd_eprotos'});
+       }
+
+# SSL file options
+$confdb = &get_config_db();
+foreach $s ([ 'olcTLSCertificateFile', 'cert' ],
+           [ 'olcTLSCertificateKeyFile', 'key' ],
+           [ 'olcTLSCACertificateFile', 'ca' ]) {
+       if ($in{$s->[1].'_def'}) {
+               &save_ldif_directive($conf, $s->[0], $confdb, undef);
+               }
+       else {
+               &valid_pem_file($in{$s->[1]}, $s->[1]) ||
+                       &error($text{'slapd_e'.$s->[1]});
+               &save_ldif_directive($conf, $s->[0], $confdb, $in{$s->[1]});
+               }
+       }
+
+# Write out the files
+&flush_file_lines();
+&unlock_slapd_files();
+if ($save_config) {
+       &lock_file($module_config_file);
+       &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("");
+
index b424192..8a4c504 100644 (file)
@@ -21,10 +21,10 @@ push(@incs, split(/\0/, $in{'d'}));
 @incs = &unique(@incs);
 
 # Write out
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 &save_directive($conf, "include", @incs);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("schema");
 &redirect("");
index e5e8143..64d82da 100644 (file)
@@ -7,7 +7,7 @@ $access{'slapd'} || &error($text{'slapd_ecannot'});
 &local_ldap_server() == 1 || &error($text{'slapd_elocal'});
 &ReadParse();
 
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 
 # Validate and store inputs
@@ -87,7 +87,7 @@ foreach $s ([ 'TLSCertificateFile', 'cert' ],
 
 # Write out the files
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 if ($save_config) {
        &lock_file($module_config_file);
        &save_module_config();
index be6692b..659816a 100644 (file)
@@ -7,7 +7,7 @@ $access{'acl'} || &error($text{'acl_ecannot'});
 &ReadParse();
 
 # Find it
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 @access = &find("access", $conf);
 $p = &parse_ldap_access($access[$in{'idx'}]);
@@ -17,7 +17,7 @@ $p = &parse_ldap_access($access[$in{'idx'}]);
        ($access[$in{'idx'}], $access[$in{'idx'}-1]);
 &save_directive($conf, "access", @access);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("up", "access", $p->{'what'});
 &redirect("edit_acl.cgi");
index ae47747..bb0e9be 100644 (file)
@@ -7,7 +7,7 @@ $access{'schema'} || &error($text{'schema_ecannot'});
 &ReadParse();
 
 # Find it includes
-&lock_file($config{'config_file'});
+&lock_slapd_files();
 $conf = &get_config();
 @incs = &find_value("include", $conf);
 $idx = &indexof($in{'file'}, @incs);
@@ -17,7 +17,7 @@ $idx > 0 || &error($text{'schema_emove'});
 ($incs[$idx-1], $incs[$idx]) = ($incs[$idx], $incs[$idx-1]);
 &save_directive($conf, "include", @incs);
 &flush_file_lines($config{'config_file'});
-&unlock_file($config{'config_file'});
+&unlock_slapd_files();
 
 &webmin_log("sup", undef, $in{'file'});
 &redirect("edit_schema.cgi");