Finished off LDAP browser
authorJamie Cameron <jcameron@webmin.com>
Wed, 7 Nov 2007 00:23:06 +0000 (00:23 +0000)
committerJamie Cameron <jcameron@webmin.com>
Wed, 7 Nov 2007 00:23:06 +0000 (00:23 +0000)
ldap-server/add.cgi [new file with mode: 0644]
ldap-server/add_form.cgi [new file with mode: 0644]
ldap-server/edit_browser.cgi
ldap-server/ldap-server-lib.pl
ldap-server/rename_browser.cgi [new file with mode: 0755]
ldap-server/sdelete_browser.cgi [new file with mode: 0644]

diff --git a/ldap-server/add.cgi b/ldap-server/add.cgi
new file mode 100644 (file)
index 0000000..be4bf61
--- /dev/null
@@ -0,0 +1,44 @@
+#!/usr/local/bin/perl
+# Create a whole new object
+
+require './ldap-server-lib.pl';
+&error_setup($text{'oadd_err'});
+&ReadParse();
+$ldap = &connect_ldap_db();
+ref($ldap) || &error($ldap);
+
+# Validate inputs
+$in{'dn1'} =~ /^\S+$/ || &error($text{'oadd_edn1'});
+$in{'dn2'} =~ /^\S+$/ || &error($text{'oadd_edn2'});
+@classes = split(/\r?\n/, $in{'classes'});
+@classes || &error($text{'oadd_eclasses'});
+foreach $c (@classes) {
+       $c =~ /^\S+$/ || &error(&text('oadd_eclass', $c));
+       }
+push(@attrs, "objectClass", \@classes);
+for($i=0; defined($in{"name_$i"}); $i++) {
+       next if ($in{"name_$i"} eq "");
+       $in{"name_$i"} =~ /^\S+$/ ||  &error(&text('oadd_ename', $i+1));
+       push(@attrs, $in{"name_$i"}, [ split(/\r?\n/, $in{"value_$i"}) ]);
+       }
+$dn = $in{'dn1'}."=".$in{'dn2'};
+$dn .= ", $in{'base'}" if ($in{'base'});
+
+# Check for a clash
+$rv = $ldap->search(base => $dn,
+                   filter => '(objectClass=*)',
+                   score => 'base');
+if ($rv && !$rv->code) {
+       ($clash) = $rv->all_entries;
+       $clash && &error(&text('oadd_eclash', "<tt>$dn</tt>"));
+       }
+
+# Create the object
+$rv = $ldap->add($dn, attr => \@attrs);
+if (!$rv || $rv->code) {
+       &error(&text('oadd_eadd', "<tt>$dn</tt>",
+                                 &ldap_error($rv)));
+       }
+
+&redirect("edit_browser.cgi?base=".&urlize($dn));
+
diff --git a/ldap-server/add_form.cgi b/ldap-server/add_form.cgi
new file mode 100644 (file)
index 0000000..f9617ba
--- /dev/null
@@ -0,0 +1,80 @@
+#!/usr/local/bin/perl
+# Show a form for adding a new object
+
+require './ldap-server-lib.pl';
+&ReadParse();
+$ldap = &connect_ldap_db();
+ref($ldap) || &error($ldap);
+
+if ($in{'clone'}) {
+       # Get original object
+       $rv = $ldap->search(base => $in{'base'},
+                           filter => '(objectClass=*)',
+                           score => 'base');
+       if (!$rv || $rv->code) {
+               &error(&text('oadd_eget', "<tt>$in{'base'}</tt>",
+                                         &ldap_error($rv)));
+               }
+       ($bo) = $rv->all_entries;
+       if ($in{'base'} =~ /^([^=]+)=([^,]+)[, ]*(.*)$/) {
+               $dn1 = $1;
+               $dn2 = $2;
+               $base = $3;
+               }
+       @classes = $bo->get_value("objectClass");
+       foreach $a ($bo->attributes()) {
+               next if ($a eq "objectClass");
+               local @av = $bo->get_value($a);
+               push(@attrs, [ $a, @av == 1 ? $av[0] : \@av ]);
+               }
+       push(@attrs, [ ], [ ]);
+       }
+else {
+       # Under some object
+       $base = $in{'base'};
+       $dn1 = "cn";
+       @attrs = ( [ ], [ ], [ ], [ ], [ ] );
+       }
+
+&ui_print_header(undef, $text{'oadd_title'}, "", "oadd");
+
+print &ui_form_start("add.cgi", "post");
+print &ui_table_start($text{'oadd_header'}, undef, 2);
+
+# New object
+print &ui_table_row($text{'oadd_dn'},
+       &ui_textbox("dn1", $dn1, 10)."=".&ui_textbox("dn2", $dn2, 40));
+
+# Parent object
+if ($base) {
+       print &ui_hidden("base", $base);
+       print &ui_table_row($text{'oadd_base'},
+               "<tt>$base</tt>");
+       }
+
+# Object classes
+print &ui_table_row($text{'oadd_classes'},
+       &ui_textarea("classes", join("\n", @classes), 4, 40));
+
+# Other attributes
+$i = 0;
+$atable = &ui_columns_start([ $text{'browser_name'}, $text{'browser_value'} ]);
+foreach $a (@attrs) {
+       $atable .= &ui_columns_row([
+               &ui_textbox("name_$i", $a->[0], 30),
+               ref($a->[1]) ?
+                       &ui_textarea("value_$i", join("\n", @{$a->[1]}),
+                                    scalar(@{$a->[1]}), 50) :
+                       &ui_textbox("value_$i", $a->[1], 50),
+               ]);
+       $i++;
+       }
+$atable .= &ui_columns_end();
+print &ui_table_row($text{'oadd_attrs'},
+       $atable);
+
+print &ui_table_end();
+print &ui_form_end([ [ undef, $text{'create'} ] ]);
+
+&ui_print_footer("edit_browser.cgi?base=".&urlize($in{'base'}),
+                $text{'browser_return'});
index 7257656..76f6b21 100755 (executable)
@@ -63,6 +63,7 @@ else {
                if ($in{'rename'}) {
                        # Rename form
                        print &ui_form_start("rename_browser.cgi", "post");
+                       print &ui_hidden("old", $in{'rename'});
                        }
                else {
                        # Delete sub-objects form
@@ -71,8 +72,8 @@ else {
                        @links = ( &select_all_link("d", 1),
                                   &select_invert_link("d", 1),
                                   "<a href='add_form.cgi?base=".
-                                  &urlize($base)."'>".
-                                  "$text{'browser_sadd'}</a>" );
+                                  &urlize($base)."'>$text{'browser_sadd'}</a>",
+                                );
                        }
                print &ui_hidden("base", $base);
                print &ui_links_row(\@links);
@@ -113,7 +114,7 @@ else {
                print &ui_links_row(\@links);
                print &ui_form_end([ [ undef,
                        $in{'rename'} ? $text{'browser_rsave'}
-                                     : $text{'browser_delete'} ] ]);
+                                     : $text{'browser_sdelete'} ] ]);
                }
        else {
                print "<i>$text{'browser_subnone'}</i><br>\n";
@@ -147,7 +148,10 @@ else {
                                   &select_invert_link("d", 1),
                                   "<a href='edit_browser.cgi?base=".
                                   &urlize($bo->dn())."&add=1&mode=attrs'>".
-                                  "$text{'browser_add'}</a>" );
+                                  "$text{'browser_add'}</a>",
+                                  "<a href='add_form.cgi?base=".
+                                  &urlize($base)."&clone=1'>".
+                                  "$text{'browser_clone'}</a>" );
                        @tds = ( "width=5", @tds );
                        }
                print &ui_hidden("base", $bo->dn());
index 5dda591..71d9a9b 100644 (file)
@@ -188,7 +188,15 @@ return undef;
 sub ldap_error
 {
 local ($rv) = @_;
-# XXX
+if (!$rv) {
+       return $text{'euknown'};
+       }
+elsif ($rv->code) {
+       return "".$rv->code;
+       }
+else {
+       return undef;
+       }
 }
 
 1;
diff --git a/ldap-server/rename_browser.cgi b/ldap-server/rename_browser.cgi
new file mode 100755 (executable)
index 0000000..3ecf389
--- /dev/null
@@ -0,0 +1,36 @@
+#!/usr/local/bin/perl
+# Change the DN of an LDAP object
+
+require './ldap-server-lib.pl';
+&error_setup($text{'rename_err'});
+&ReadParse();
+$ldap = &connect_ldap_db();
+ref($ldap) || &error($ldap);
+
+# Get the object
+$rv = $ldap->search(base => $in{'old'},
+                    filter => '(objectClass=*)',
+                    score => 'base');
+if (!$rv || $rv->code) {
+       &error(&ldap_error($rv));
+       }
+($bo) = $rv->all_entries;
+$bo || &error(&text('rename_eget', "<tt>$in{'old'}</tt>"));
+
+# Work out the new DN parts
+$in{'rename'} =~ /=/ || &error($text{'rename_enew'});
+($newprefix, $newrest) = split(/,/, $in{'rename'}, 2);
+
+# Do the rename
+$rv = $ldap->moddn($bo->dn(),
+                  newrdn => $newprefix,
+                  newsuperior => $newrest);
+if (!$rv || $rv->code) {
+       &error(&text('rename_erename', "<tt>".$bo->dn()."</tt>",
+                                      "<tt>$in{'rename'}</tt>",
+                                      &ldap_error($rv)));
+       }
+
+# Return to object
+&redirect("edit_browser.cgi?base=".&urlize($in{'base'})."&mode=subs");
+
diff --git a/ldap-server/sdelete_browser.cgi b/ldap-server/sdelete_browser.cgi
new file mode 100644 (file)
index 0000000..d07c60f
--- /dev/null
@@ -0,0 +1,30 @@
+#!/usr/local/bin/perl
+# Delete an entire LDAP object
+
+require './ldap-server-lib.pl';
+&error_setup($text{'sdelete_err'});
+&ReadParse();
+$ldap = &connect_ldap_db();
+ref($ldap) || &error($ldap);
+@d = split(/\0/, $in{'d'});
+@d || &error($text{'delete_enone'});
+
+# Get and remove each object
+foreach $d (@d) {
+       $rv = $ldap->search(base => $d,
+                           filter => '(objectClass=*)',
+                           score => 'base');
+       if (!$rv || $rv->code) {
+               &error(&ldap_error($rv));
+               }
+       ($bo) = $rv->all_entries;
+       $bo || &error(&text('sdelete_edn', "<tt>$d</tt>"));
+
+       $rv = $ldap->delete($d);
+       if (!$rv || $rv->code) {
+               &error(&text('sdelete_edel', "<tt>$d</tt>", &ldap_error($rv)));
+               }
+       }
+
+# Return to object
+&redirect("edit_browser.cgi?base=".&urlize($in{'base'})."&mode=subs");