Started work on access control page
authorJamie Cameron <jcameron@webmin.com>
Sun, 16 Dec 2007 00:59:03 +0000 (00:59 +0000)
committerJamie Cameron <jcameron@webmin.com>
Sun, 16 Dec 2007 00:59:03 +0000 (00:59 +0000)
ldap-server/acl_form.cgi [new file with mode: 0644]
ldap-server/edit_acl.cgi
ldap-server/lang/en
ldap-server/ldap-server-lib.pl

diff --git a/ldap-server/acl_form.cgi b/ldap-server/acl_form.cgi
new file mode 100644 (file)
index 0000000..4b72b19
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/local/bin/perl
+# Show the details of one access control rule
+
+require './ldap-server-lib.pl';
+&local_ldap_server() == 1 || &error($text{'slapd_elocal'});
+$access{'acl'} || &error($text{'acl_ecannot'});
+&ReadParse();
+
+# Page header
+$conf = &get_config();
+@access = &find("access", $conf);
+if ($in{'new'}) {
+       &ui_print_header(undef, $text{'eacl_title1'}, "");
+       $p = { 'what' => '*',
+              'by' => [ ] };
+       }
+else {
+       &ui_print_header(undef, $text{'eacl_title2'}, "");
+       $acl = $access[$in{'idx'}];
+       $p = &parse_ldap_access($acl);
+       }
+
+# Form header
+print &ui_form_start("acl_save.cgi", "post");
+print &ui_table_start($text{'eacl_header'}, undef, 2);
+
+# Granting to what object
+$what = $p->{'what'} eq '*' ? 1 : 0;
+if ($p->{'what'} =~ /^dn(\.(\S+))?=(.*)$/i) {
+       $dn = $3;
+       $style = $2;
+       }
+print &ui_table_row($text{'eacl_what'},
+       &ui_radio_table("what", $what,
+               [ [ 1, $text{'eacl_what1'} ],
+                 [ 0, $text{'eacl_what0'},
+                   &ui_textbox("what_dn", $dn, 30)." ".
+                   $text{'eacl_mtype'}." ".
+                   &ui_select("what_style", $style,
+                              [ [ '', $text{'default'} ],
+                                map { [ $_, $text{'eacl_'.$_} ] }
+                                    @acl_dn_styles ]) ] ])."\n".
+       &ui_checkbox("filter_on", 1, $text{'eacl_filter'}, $p->{'filter'})." ".
+       &ui_textbox("filter", $p->{'filter'}, 40)."<br>\n".
+       &ui_checkbox("attrs_on", 1, $text{'eacl_attrs'}, $p->{'attrs'})." ".
+       &ui_textbox("attrs", $p->{'attrs'}, 40) );
+
+# Access rights table
+# XXX
+
+# Form and page end
+print &ui_table_end();
+if ($in{'new'}) {
+       print &ui_form_end([ [ undef, $text{'create'} ] ]);
+       }
+else {
+       print &ui_form_end([ [ undef, $text{'save'} ],
+                            [ 'delete', $text{'delete'} ] ]);
+       }
+&ui_print_footer("edit_acl.cgi", $text{'acl_return'});
+
index b87f0f5..c5be20d 100644 (file)
@@ -1,9 +1,47 @@
 #!/usr/local/bin/perl
-# Show access control settings from config
+# List all access control settings from ldap server config
 
 require './ldap-server-lib.pl';
 &local_ldap_server() == 1 || &error($text{'slapd_elocal'});
 $access{'acl'} || &error($text{'acl_ecannot'});
 &ui_print_header(undef, $text{'acl_title'}, "", "acl");
 
+$conf = &get_config();
+@access = &find("access", $conf);
+@crlinks = ( "<a href='acl_form.cgi?new=1'>$text{'acl_add'}</a>" );
+if (@access) {
+       # Show table of ACLs
+       print &ui_form_start("delete_acls.cgi", "post");
+       @links = ( &select_all_link("d"), &select_invert_link("d"), @crlinks );
+       print &ui_links_row(\@links);
+       @tds = ( "width=5", "width=30%", "width=65%", "width=5%" );
+       print &ui_columns_start([ "", $text{'acl_what'},
+                                 $text{'acl_who'}, $text{'acl_move'} ],
+                               100, 0, \@tds);
+       $i = 0;
+       foreach $a (@access) {
+               $mover = &ui_up_down_arrows(
+                       "up_acl.cgi?idx=$i",
+                       "down_acl.cgi?idx=$i",
+                       $i > 1,
+                       $i && $i < @access-1);
+               $p = &parse_ldap_access($a);
+               print &ui_checked_columns_row([
+                       "<a href='acl_form.cgi?idx=$i'>$p->{'whatdesc'}</a>",
+                       $p->{'bydesc'},
+                       $mover,
+                       ], \@tds, "d", $i);
+               $i++;
+               }
+       print &ui_columns_end();
+       print &ui_links_row(\@links);
+       print &ui_form_end([ [ undef, $text{'acl_delete'} ] ]);
+       }
+else {
+       # None yet, meaning defaults
+       print "<b>$text{'acl_none'}</b><p>\n";
+       print &ui_links_row(\@crlinks);
+       }
+
+&ui_print_footer("", $text{'index_return'});
 
index d447af0..f657573 100644 (file)
@@ -94,6 +94,12 @@ schema_ecannot=You are not allowed to manage the LDAP schema
 
 acl_title=LDAP Access Control
 acl_ecannot=You are not allowed to configure LDAP access control
+acl_what=Objects
+acl_who=Access granted
+acl_move=Move
+acl_none=No access control rules have been defined yet. All objects in the LDAP database will be readable by all users.
+acl_delete=Delete Selected Rules
+acl_add=Add a new access control rule.
 
 browser_title=Browse Database
 browser_econn=The LDAP browser cannot be used : $1
@@ -250,3 +256,28 @@ acl_browser=Can browse and edit database?
 acl_create=Can create new tree?
 acl_start=Can start and stop LDAP server?
 acl_apply=Can apply configuration changes?
+
+access_desc=$2 by $1
+access_self=self
+access_users=authenticated users
+access_anon=anonymous users
+access_read=read
+access_write=write
+access_auth=authenticate
+access_all=anyone
+access_any=All objects
+
+eacl_title1=Create Access Control Rule
+eacl_title2=Edit Access Control Rule
+eacl_header=LDAP database access control rule details
+eacl_what=Granting access to
+eacl_what1=All objects
+eacl_what0=Object with DN
+eacl_mtype=match type
+eacl_regex=regular expression
+eacl_base=this object only
+eacl_one=one level below
+eacl_subtree=entire subtree
+eacl_children=only children
+eacl_filter=Limit with object filter :
+eacl_attrs=Limit to listed attributes :
index 4f42176..ad0231a 100644 (file)
@@ -11,6 +11,7 @@ eval "use Net::LDAP";
 if ($@) { $net_ldap_error = $@; }
 
 @search_attrs = ( 'objectClass', 'cn', 'dn', 'uid' );
+@acl_dn_styles = ( 'regex', 'base', 'one', 'subtree', 'children' );
 
 # connect_ldap_db()
 # Attempts to connect to an LDAP server. Returns a handle on success or an
@@ -159,6 +160,11 @@ while(<CONF>) {
                $dir->{'values'} = [ &split_quoted_string($value) ];
                push(@rv, $dir);
                }
+       elsif (/^\s+(\S.*)$/ && @rv) {
+               # Found a continuation line, with extra values
+               local $value = $1;
+               push(@{$rv[$#rv]->{'values'}}, &split_quoted_string($value));
+               }
        $lnum++;
        }
 close(CONF);
@@ -397,5 +403,53 @@ else {
        }
 }
 
+# parse_ldap_access(&directive)
+# Convert a slapd.conf directive into a more usable access control rule hash
+sub parse_ldap_access
+{
+local ($a) = @_;
+local @v = @{$a->{'values'}};
+local $p = { };
+shift(@v);                     # Remove to
+$p->{'what'} = shift(@v);      # Object
+if ($v[0] =~ /^filter=(\S+)/) {
+       # Filter added to what
+       $p->{'filter'} = $1;
+       shift(@v);
+       }
+if ($v[0] =~ /^attrs=(\S+)/) {
+       # Attributes added to what
+       $p->{'attrs'} = $1;
+       shift(@v);
+       }
+local @descs;
+while(@v) {
+       shift(@v);              # Remove by
+       local $by = { 'who' => shift(@v),
+                     'access' => shift(@v) };
+       if (@v && $v[0] ne 'by') {
+               $by->{'control'} = shift(@v);
+               }
+       local $whodesc = $by->{'who'} eq 'self' ? $text{'access_self'} :
+                        $by->{'who'} eq 'users' ? $text{'access_users'} :
+                        $by->{'who'} eq 'anonymous' ? $text{'access_anon'} :
+                        $by->{'who'} eq '*' ? $text{'access_all'} :
+                                              "<tt>$by->{'who'}</tt>";
+       local $adesc = $text{'access_'.$by->{'access'}} ||
+                      "<tt>$by->{'access'}</tt>";
+       $adesc = ucfirst($adesc) if (!@descs);
+       push(@descs, &text('access_desc', $whodesc, $adesc));
+       push(@{$p->{'by'}}, $by);
+       }
+$p->{'bydesc'} = join(", ", @descs);
+if ($p->{'what'} eq '*') {
+       $p->{'whatdesc'} = $text{'access_any'};
+       }
+else {
+       $p->{'whatdesc'} = "<tt>$p->{'what'}</tt>";
+       }
+return $p;
+}
+
 1;