diff --git a/mysql/lang/en b/mysql/lang/en index 786ba4565..4b38f85d2 100644 --- a/mysql/lang/en +++ b/mysql/lang/en @@ -335,6 +335,8 @@ dbs_hosts=From host permissions dbs_add=Create new database permissions. dbs_all=All dbs_none=None +dbs_except=All, except +dbs_except_and=and dbs_return=database permissions dbs_derr=Failed to delete database permissions dbs_enone=No databases selected diff --git a/mysql/list_dbs.cgi b/mysql/list_dbs.cgi index b127edb94..b08722ba1 100755 --- a/mysql/list_dbs.cgi +++ b/mysql/list_dbs.cgi @@ -40,7 +40,8 @@ if (@{$d->{'data'}}) { : &html_escape($u->[0])); my @priv; my ($allprivs, $noprivs) = (1, 1); - foreach my $f (&priv_fields('db')) { + my @priv_fields = &priv_fields('db'); + foreach my $f (@priv_fields) { if ($u->[$fieldmap{$f->[0]}] eq 'Y') { push(@priv, $f->[1]); $noprivs = 0; @@ -51,7 +52,7 @@ if (@{$d->{'data'}}) { } push(@cols, $allprivs ? $text{'users_all'} : $noprivs ? $text{'users_none'} : - join(" | ", @priv)); + &format_privs(\@priv, \@priv_fields)); print &ui_checked_columns_row(\@cols, \@tds, "d", join(" ", $u->[0], $u->[1], $u->[2])); } diff --git a/mysql/list_users.cgi b/mysql/list_users.cgi index 2c29dc4b4..878f20cac 100755 --- a/mysql/list_users.cgi +++ b/mysql/list_users.cgi @@ -36,7 +36,8 @@ foreach $u (@{$d->{'data'}}) { } my @priv; my ($allprivs, $noprivs) = (1, 1); - foreach my $f (&priv_fields('user')) { + my @priv_fields = &priv_fields('user'); + foreach my $f (@priv_fields) { if ($u->[$fieldmap{$f->[0]}] eq 'Y') { push(@priv, $f->[1]); $noprivs = 0; @@ -46,7 +47,8 @@ foreach $u (@{$d->{'data'}}) { } } push(@cols, $allprivs ? $text{'users_all'} : - $noprivs ? $text{'users_none'} : join(" | ", @priv)); + $noprivs ? $text{'users_none'} : + &format_privs(\@priv, \@priv_fields)); print &ui_checked_columns_row(\@cols, \@tds, "d", $u->[0]." ".$u->[1]); $i++; } diff --git a/mysql/mysql-lib.pl b/mysql/mysql-lib.pl index 87b1fa69a..d1dc1d7d7 100755 --- a/mysql/mysql-lib.pl +++ b/mysql/mysql-lib.pl @@ -2132,5 +2132,91 @@ return 'password' if ($@); # Old version without plugins return $rv->{'data'}->[0]->[0] =~ /unix_socket/i ? 'socket' : 'password'; } +# format_privs(&privs, &privs_fields) +# Returns best formatted string for a set of privileges +sub format_privs +{ +my ($privs, $privs_fields) = @_; +my @privs_all = map { lc($_->[1]) } @{$privs_fields}; +my @privs_cur = map { lc($_) } @{$privs}; +my $simplify_privs = sub { + my @privs = @_; + my %groups = ( + 'table_data' => [], + 'tables' => [], + 'view' => [], + 'routine' => [], + ); + my @others = (); + foreach my $priv (@privs) { + if ($priv =~ /^(select|insert|update|delete) table data$/) { + push @{$groups{'table_data'}}, $1; + } + elsif ($priv =~ /^(create|drop|alter|create temp|lock) tables?$/) { + push @{$groups{'tables'}}, $1; + } + elsif ($priv =~ /^(create|show) view$/) { + push @{$groups{'view'}}, $1; + } + elsif ($priv =~ /^(create|alter) routine$/) { + push @{$groups{'routine'}}, $1; + } + else { + push @others, $priv; + } + } + # Build simplified string + my @simplified = (); + # Handle 'table data' + if (@{$groups{'table_data'}}) { + my $table_data_str = join(', ', @{$groups{'table_data'}}); + $table_data_str =~ s/(.*),/$1 $text{'dbs_except_and'}/ + if (@{$groups{'table_data'}} > 1); + push(@simplified, "$table_data_str table data"); + } + # Handle 'tables' + if (@{$groups{'tables'}}) { + my $tables_str = join(', ', @{$groups{'tables'}}); + $tables_str =~ s/(.*),/$1 $text{'dbs_except_and'}/ + if (@{$groups{'tables'}} > 1); + $tables_str .= ' tables'; + $tables_str =~ s/create temp tables/create temporary tables/; + push(@simplified, $tables_str); + } + # Handle 'view' + if (@{$groups{'view'}}) { + my $view_str = join(" $text{'dbs_except_and'} ", + @{$groups{'view'}}); + push(@simplified, "$view_str view"); + } + # Handle 'routine' + if (@{$groups{'routine'}}) { + my $routine_str = join(" $text{'dbs_except_and'} ", + @{$groups{'routine'}}); + push(@simplified, "$routine_str routine"); + } + # Add other privileges + push(@simplified, @others); + return join('; ', @simplified); + }; + +if (@privs_cur >= int(0.7 * @privs_all)) { + my %missing = map { $_ => 1 } @privs_all; + delete(@missing{@privs_cur}); + my @missing_privs = keys %missing; + my $missing_formatted = $simplify_privs->(@missing_privs); + if (@missing_privs > 1) { + $privs_formatted = "$text{'dbs_except'} ($missing_formatted)"; + } + else { + $privs_formatted = "$text{'dbs_except'} $missing_formatted"; + } + } +else { + $privs_formatted = $simplify_privs->(@privs_cur); + } +return ucfirst($privs_formatted); +} + 1;