More work on LDAP schema management
authorJamie Cameron <jcameron@webmin.com>
Wed, 12 Dec 2007 00:49:47 +0000 (00:49 +0000)
committerJamie Cameron <jcameron@webmin.com>
Wed, 12 Dec 2007 00:49:47 +0000 (00:49 +0000)
ldap-server/edit_schema.cgi [new file with mode: 0644]
ldap-server/lang/en
ldap-server/ldap-server-lib.pl
ldap-server/save_schema.cgi [new file with mode: 0644]

diff --git a/ldap-server/edit_schema.cgi b/ldap-server/edit_schema.cgi
new file mode 100644 (file)
index 0000000..281589f
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/local/bin/perl
+# Select which schema files are included
+
+require './ldap-server-lib.pl';
+&local_ldap_server() == 1 || &error($text{'slapd_elocal'});
+&ui_print_header(undef, $text{'schema_title'}, "", "schema");
+&ReadParse();
+
+# Get included schemas
+$conf = &get_config();
+foreach $i (&find_value("include", $conf)) {
+       if ($i =~ /^(.*)\// && $1 eq $config{'schema_dir'}) {
+               $incs{$i} = ++$n;
+               }
+       }
+
+# Show a table of all known schema files, with checkboxes
+print $text{'schema_pagedesc'},"<p>\n";
+@tds = ( "width=5", undef, undef, "width=10%", "width=5%" );
+print &ui_form_start("save_schema.cgi", "post");
+print &ui_columns_start([ "",
+                         $text{'schema_file'},
+                         $text{'schema_desc'},
+                         $text{'schema_act'},
+                         $text{'schema_move'} ], 100, 0, \@tds);
+@files = sort { &schema_sorter } &list_schema_files();
+for($i=0; $i<@files; $i++) {
+       $s = $files[$i];
+       @acts = ( "<a href='view_sfile.cgi?file=".&urlize($s->{'file'})."'>".
+                 "$text{'schema_view'}</a>",
+                 "<a href='edit_sfile.cgi?file=".&urlize($s->{'file'})."'>".
+                  "$text{'schema_edit'}</a>" );
+       if ($incs{$s->{'file'}}) {
+               $mover = &ui_up_down_arrows(
+                       "up_schema.cgi?file=".&urlize($s->{'file'}),
+                       "down_schema.cgi?file=".&urlize($s->{'file'}),
+                       $i > 1,
+                       $i && $i < @files-1 && $incs{$files[$i+1]->{'file'}});
+               }
+       else {
+               $mover = "";
+               }
+       print &ui_checked_columns_row(
+               [ $s->{'name'},
+                 $s->{'desc'} || $s->{'file'},
+                 &ui_links_row(\@acts),
+                 $mover,
+               ],
+               \@tds, "d", $s->{'file'}, $incs{$s->{'file'}},
+               $s->{'name'} eq 'core');
+       }
+print &ui_columns_end();
+print &ui_form_end([ [ undef, $text{'save'} ] ]);
+
+&ui_print_footer("", $text{'index_return'});
+
+sub schema_sorter
+{
+return ($incs{$a->{'file'}} || 999) <=> ($incs{$b->{'file'}} || 999);
+}
+
index df6de0c..ae27c0b 100644 (file)
@@ -65,6 +65,14 @@ slapd_gencertdesc=To run your LDAP server in TLS mode, an SSL certificate and pr
 slapd_gencertwarn=Warning - your existing certificate will no longer be used.
 
 schema_title=Manage Schema
+schema_file=Schema name
+schema_desc=Description
+schema_pagedesc=The LDAP schema determines which object classes and attributes can be stored in your LDAP database. This page allows you to select which schema types are supported by your server - but be careful de-selecting any entries that are used by existing objects.
+schema_err=Failed to save schema
+schema_move=Move
+schema_act=Actions..
+schema_view=View
+schema_edit=Edit
 
 acl_title=LDAP Access Control
 
@@ -170,6 +178,8 @@ log_stop=Stopped LDAP server
 log_start=Started LDAP Server
 log_apply=Applied configuration
 log_slapd=Changed LDAP server configuration
+log_schema=Changed enabled LDAP schemas
+log_gencert=Generated new SSL certificate
 
 gencert_title=Generate SSL Certificate
 gencert_header=New SSL certificate details
index ff65ab8..3a3ebc9 100644 (file)
@@ -237,8 +237,9 @@ sub start_ldap_server
 {
 local $cmd = $config{'start_cmd'} || $config{'slapd'};
 local $out = &backquote_logged("$cmd 2>&1 </dev/null");
-return $? ? &text('start_ecmd', "<tt>$cmd</tt>",
-                 "<pre>".&html_escape($out)."</pre>") : undef;
+return $? || $out =~ /line\s+(\d+)/ ?
+       &text('start_ecmd', "<tt>$cmd</tt>",
+             "<pre>".&html_escape($out)."</pre>") : undef;
 }
 
 # stop_ldap_server()
@@ -325,5 +326,39 @@ if ($config{'config_file'} =~ /^(\S+)\/([^\/]+)$/) {
 return undef;
 }
 
+# list_schema_files()
+# Returns a list of hashes, each of which describes one possible schema file
+sub list_schema_files
+{
+local @rv;
+opendir(SCHEMA, $config{'schema_dir'});
+foreach my $f (readdir(SCHEMA)) {
+       if ($f =~ /^(\S+)\.schema$/) {
+               local $name = $1;
+               local $lref = &read_file_lines("$config{'schema_dir'}/$f", 1);
+               local $desc;
+               foreach my $l (@$lref) {
+                       if ($l !~ /^\#+\s*\$/ && $l =~ /^\#+\s*(\S.*)/) {
+                               $desc .= $1." ";        # Comment
+                               }
+                       elsif ($l !~ /\S/) {
+                               last;                   # End of header
+                               }
+                       else {
+                               last if ($desc);        # End of comment
+                               }
+                       }
+               $desc ||= $text{'schema_desc_'.$name};
+               push(@rv, { 'file' => "$config{'schema_dir'}/$f",
+                           'name' => $name,
+                           'desc' => $desc,
+                           'core' => $name eq 'core' });
+               }
+       }
+closedir(SCHEMA);
+return sort { $b->{'core'} <=> $a->{'core'} ||
+             $a->{'name'} cmp $b->{'name'} } @rv;
+}
+
 1;
 
diff --git a/ldap-server/save_schema.cgi b/ldap-server/save_schema.cgi
new file mode 100644 (file)
index 0000000..002a000
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/local/bin/perl
+# Save included schema files
+
+require './ldap-server-lib.pl';
+&error_setup($text{'schema_err'});
+&local_ldap_server() == 1 || &error($text{'slapd_elocal'});
+&ReadParse();
+
+# Get non-schema includes
+$conf = &get_config();
+foreach $i (&find_value("include", $conf)) {
+       if ($i !~ /^(.*)\/(\S+)$/ || $1 ne $config{'schema_dir'} ||
+                                    $2 eq 'core.schema') {
+               push(@incs, $i);
+               }
+       }
+
+# Build new list of includes
+push(@incs, split(/\0/, $in{'d'}));
+@incs = &unique(@incs);
+
+# Write out
+&lock_file($config{'config_file'});
+&save_directive($conf, "include", @incs);
+&flush_file_lines($config{'config_file'});
+&unlock_file($config{'config_file'});
+
+&webmin_log("schema");
+&redirect("");
+