Author: kmachalkova
Date: Tue Nov 18 17:22:41 2008
New Revision: 53387
URL: http://svn.opensuse.org/viewcvs/yast?rev=53387&view=rev
Log:
- Rewrite of Perl agent to store sudoers data in
non-associative data structure + adapting
business logic to use lists, not maps, added
up/down buttons to help setting sudo rules
priorities (bnc#439164, bnc#365178)
Modified:
trunk/sudo/agents/ag_etc_sudoers
trunk/sudo/agents/sudo.scr
trunk/sudo/src/Sudo.ycp
trunk/sudo/src/complex.ycp
trunk/sudo/src/dialog-cmnd.ycp
trunk/sudo/src/dialog-host.ycp
trunk/sudo/src/dialog-runas.ycp
trunk/sudo/src/dialog-spec.ycp
trunk/sudo/src/dialog-user.ycp
trunk/sudo/src/dialogs.ycp
Modified: trunk/sudo/agents/ag_etc_sudoers
URL: http://svn.opensuse.org/viewcvs/yast/trunk/sudo/agents/ag_etc_sudoers?rev=53387&r1=53386&r2=53387&view=diff
==============================================================================
--- trunk/sudo/agents/ag_etc_sudoers (original)
+++ trunk/sudo/agents/ag_etc_sudoers Tue Nov 18 17:22:41 2008
@@ -11,7 +11,7 @@
my $filename = "/etc/sudoers";
-my %data; #= (
+my @data2 = (); #= (
# "Host_Alias" => [ ["# Host Alias Specification","SERVERS", "ns, www, mail"],["","FOO", "www.foo.org"] ],
# "User_Alias" => [ ["# User Alias Specification", "BAT","foobar"], ["","WWW", "wwwrun"] ],
# "Cmnd_Alias" => [ ["# Command Alias Specification", "HALT", "/usr/sbin/halt, /usr/sbin/shutdown -h now,"], ["","REBOOT", "/sbin/reboot"] ],
@@ -21,6 +21,8 @@
# '%wheel' => [ ["# Same thing without password", "ALL", "(ALL) NOPASSWD: HALT,REBOOT"] ],
# );
+
+
sub parse_file {
if (!open(INFILE, $filename)) {
@@ -37,18 +39,19 @@
next;
}
- my $alias = "";
- my @entry = ();
+ my $alias = "";
+
+ my @entry2 = ();
if (/^(\S+)\s+(\S+)\s*=\s*([^#]*)/) {
$alias =$1;
- push(@entry,$comment,$2,$3);
+ push(@entry2, $comment, $alias, $2, $3);
}
elsif (/^(\S+)\s+(\S+)/) {
$alias =$1;
- push(@entry,$comment,$2,"");
+ push(@entry2, $comment, $alias, $2);
}
- push (@{$data{$alias}}, \@entry);
+ push (@data2, \@entry2);
$comment = "";
}
@@ -57,26 +60,18 @@
return 1;
}
-sub store_key {
- my $key = $_[0];
+sub store_line {
+ my $line = $_[0];
+ my ($comment, $type, $name, $members) = @{$line};
- if (exists ($data{$key})) {
- my @key_data = @{$data{$key}};
- foreach my $entry (@key_data) {
- my ($comment, $name, $members) = @{$entry};
-
- if($comment){
- print OUTFILE $comment;
- }
- if($name) {
- if($members) {
- print OUTFILE $key,"\t", $name, " = ", $members, "\n";
- }
- else {
- print OUTFILE $key,"\t", $name,"\n";
- }
- }
- }
+ if($comment){
+ print OUTFILE $comment;
+ }
+ if($members) {
+ print OUTFILE $type,"\t", $name, " = ", $members, "\n";
+ }
+ else {
+ print OUTFILE $type,"\t", $name,"\n";
}
}
@@ -85,30 +80,10 @@
open(OUTFILE,">$filename.YaST2.new")
or return y2error("Could not open file $filename.YaST2.new for writing: %1", $!), 0;
- #Store Host Aliases first and delete old stuff
- store_key("Host_Alias");
- delete($data{"Host_Alias"});
-
- #Store User Aliases next
- store_key("User_Alias");
- delete($data{"User_Alias"});
-
- #Store Command Aliases next
- store_key("Cmnd_Alias");
- delete($data{"Cmnd_Alias"});
-
- #Defaults next
- store_key("Defaults");
- delete($data{"Defaults"});
-
- #Runas Aliases then
- store_key("Runas_Alias");
- delete($data{"Runas_Alias"});
-
#Dump the rest
- foreach my $key (keys %data) {
- store_key($key);
- delete($data{$key});
+ foreach my $line (@data2) {
+ store_line($line);
+ #delete($data{$key});
}
close(OUTFILE);
@@ -136,35 +111,14 @@
while ( <STDIN> ) {
my ($command, $path, $argument) = ycp::ParseCommand ($_);
- if ($command eq "Dir") {
- if ($path eq ".") {
- my @keys = keys %data;
- ycp::Return(\@keys);
- }
- else {
- ycp::Return([]);
- }
- }
-
- elsif($command eq "Read") {
- #Remove leading '.'
- #$path =~ s/\.//;
- my @p = ycp::PathComponents(\$path);
-
- if (exists($data{$p[0]})) {
- ycp::Return(\@{$data{$p[0]} });
- }
- else {
- y2error("Unrecognized key '$p[0]'");
- ycp::Return(undef);
- }
+ if($command eq "Read") {
+ ycp::Return(\@data2);
}
elsif($command eq "Write") {
my $result = "true";
- if ($path eq "." && ref($argument) eq "HASH") {
- %data = %{$argument};
-
+ if ($path eq "." && ref($argument) eq "ARRAY") {
+ @data2 = @{$argument};
}
elsif ($path eq "." && !defined($argument)) {
$result = store_file() ? "true" : "false";
@@ -188,4 +142,4 @@
}
#Debug only !
-#print STDERR Dumper(\%data);
+#print STDERR Dumper(\@data2);
Modified: trunk/sudo/agents/sudo.scr
URL: http://svn.opensuse.org/viewcvs/yast/trunk/sudo/agents/sudo.scr?rev=53387&r1=53386&r2=53387&view=diff
==============================================================================
--- trunk/sudo/agents/sudo.scr (original)
+++ trunk/sudo/agents/sudo.scr Tue Nov 18 17:22:41 2008
@@ -8,18 +8,21 @@
* Authors:
* Bubli
* Example:
- * Dir(.sudo)
- * (["User_Alias","Runas_Alias","Host_Alias","ALL", "%wheel"] )
*
- * Read(.sudo.User_Alias)
- * (["WEBMASTERS = will, wendy, wim"])
- *
- * Write(.sudo.Host_Alias, "SERVERS = master, mail, www, ns")
+ * Read(.sudo)
+ * ([
+ * ["#We let root and any user in group wheel run any command on any host as any user.\n", "root", "ALL", "(ALL) ALL"],
+ * ["", "%wheel", "ALL", "(ALL) ALL"]
+ * ]
+ * )
+ * Write(.sudo, [ ["#first rule", "user", "HOST", "rule1"], ["#second rule", "otheruser", "HOST", "rule2"] ])
* (true)
*
* $Id: sudo.scr 11113 2005-10-20 14:15:16Z kmachalkova $
*
- * Fore more information about possible keys and values
+ * Read returns and Write accepts list of lists of strings, ordered as follows:
+ # ["comment to this rule or alias", username | keyword, hostname | alias name, rule | csv list ]
+ * Fore more information about possible keywords, aliases and values
* consult with the sudoers man pages `man sudoers`.
*/
Modified: trunk/sudo/src/Sudo.ycp
URL: http://svn.opensuse.org/viewcvs/yast/trunk/sudo/src/Sudo.ycp?rev=53387&r1=53386&r2=53387&view=diff
==============================================================================
--- trunk/sudo/src/Sudo.ycp (original)
+++ trunk/sudo/src/Sudo.ycp Tue Nov 18 17:22:41 2008
@@ -51,7 +51,7 @@
*/
boolean modified = false;
-integer sl = 500;
+integer sl = 10;
/**
* Data was modified?
* @return true if modified
@@ -66,100 +66,100 @@
global string ValidCharsUsername = deletechars (String::CGraph (), "'\"") + " ";
-map > settings = $[];
+list < list <string> > settings2 = [];
map host_aliases = $[];
+list< map > host_aliases2 = [];
map user_aliases = $[];
+list< map > user_aliases2 = [];
map cmnd_aliases = $[];
+list< map > cmnd_aliases2 = [];
map runas_aliases = $[];
+list< map > runas_aliases2 = [];
list defaults = [];
list < map > user_specs = [];
+list < map > rules = [];
list <string> deleted_specs = [];
global list <string> all_users = [];
-boolean ReadSudoSettings() {
- list <string> keys = SCR::Dir(.sudo);
+boolean ReadSudoSettings2() {
+ settings2 = ( list < list <string> >)SCR::Read(.sudo);
+ y2milestone("Sudo settings %1", settings2);
+
+ foreach( list <string> line, settings2, {
+ string type = line[1]:"";
+
+ switch (type) {
+ case "Host_Alias": {
+ list <string> lst = splitstring(deletechars( line[3]:""," \t"), ",");
+ host_aliases2 = add( host_aliases2, $[ "c": line[0]: "", "name": line[2]:"", "mem": lst ] );
+ break;
+ }
+ case "User_Alias": {
+ list <string> lst = splitstring(deletechars( line[3]:""," \t"), ",");
+ user_aliases2 = add( user_aliases2, $[ "c": line[0]: "", "name": line[2]:"", "mem": lst ] );
+ break;
+ }
+ case "Cmnd_Alias": {
+ list <string> lst = maplist(string s, splitstring( line[3]:"", ","), {
+ return (substring(s,findfirstnotof(s," \t")));
+ });
+ cmnd_aliases2 = add( cmnd_aliases2, $[ "c": line[0]: "", "name": line[2]:"", "mem": lst ] );
+ break;
+ }
+ case "Runas_Alias": {
+ list <string> lst = splitstring(deletechars( line[3]:""," \t"), ",");
+ runas_aliases2 = add( runas_aliases2, $[ "c": line[0]: "", "name": line[2]:"", "mem": lst ] );
+ break;
+ }
+ case "Defaults": {
+ //do nothing, keep defaults untouched
+ defaults = add(defaults,line);
+ break;
+ }
+ //rules remained
+ default: {
+ map m = $[];
+ list <string> cmd = [];
+
+ if ( regexpmatch(type, "^.*\\\\.*$"))
+ type = regexpsub(type, "^(.*)\\\\(.*)$", "\\1\\2");
+ m["user"] = type;
+
+ m["host"] = line[2]:"";
+
+ //match "(.*)"
+ if (regexpmatch(line[3]:"","\\(.*\\)")){
+ m["run_as"] = regexpsub(line[3]:"","(\\(.*\\))", "\\1");
+ }
- if (keys != [])
- foreach (string key, keys, {
- list < list <string> > val = (list < list <string> >) SCR::Read(add(.sudo, key));
- if (val != nil) settings[key] = val;
- });
-
- y2milestone("settings %1", settings);
-
- foreach(string opt_key, list < list <string> > opt_val, settings, {
- // #comment \n key value = porn.bat
- // is returned as key : [["#comment","value","porn.bat"]]
- // wrk[0] -> comment, wrk[1] -> value, wrk[2] -> porn.bat
- foreach(list <string> wrk, opt_val, {
- switch (opt_key) {
- case "Host_Alias": {
- host_aliases[ wrk[1]:"" ] = splitstring(deletechars(wrk[2]:""," \t"), ",");
- break;
- }
- case "User_Alias": {
- user_aliases[ wrk[1]:"" ] = splitstring(deletechars(wrk[2]:""," \t"), ",");
- break;
- }
- case "Cmnd_Alias": {
- cmnd_aliases[ wrk[1]:""] = maplist(string s, splitstring( wrk[2]:"", ","), {
- return (substring(s,findfirstnotof(s," \t")));
- });
- break;
- }
- case "Runas_Alias": {
- runas_aliases[ wrk[1]:"" ] = splitstring(deletechars(wrk[2]:""," \t"), ",");
- break;
- }
- case "Defaults": {
- //do nothing, keep defaults untouched
- defaults = add(defaults,wrk);
- break;
- }
- //User specifications remained
- default: {
- map m = $[];
- list <string> cmd = [];
-
- if ( regexpmatch(opt_key, "^.*\\\\.*$"))
- opt_key = regexpsub(opt_key, "^(.*)\\\\(.*)$", "\\1\\2");
- m["user"] = opt_key;
-
- m["host"] = wrk[1]:"";
-
- //match "(.*)"
- if (regexpmatch(wrk[2]:"","\\(.*\\)")){
- m["run_as"] = regexpsub(wrk[2]:"","(\\(.*\\))", "\\1");
- }
-
- if(issubstring(wrk[2]:"","NOPASSWD:")) {
- m["no_passwd"] = (boolean) true;
- }
- else {
- m["no_passwd"] = (boolean) false;
- }
-
- cmd = splitstring(wrk[2]:"","):");
- m["commands"] = (list <string>) splitstring (cmd[ size(cmd) -1 ]:"",",");
- m["commands"] = maplist(string s, m["commands"]:[],{
- return (substring(s,findfirstnotof(s," \t")));
- });
- m["comment"] = wrk[0]:"";
+ if(issubstring(line[3]:"","NOPASSWD:")) {
+ m["no_passwd"] = (boolean) true;
+ }
+ else {
+ m["no_passwd"] = (boolean) false;
+ }
- user_specs = add(user_specs,m);
- break;
- }
+ cmd = splitstring(line[3]:"","):");
+ m["commands"] = (list <string>) splitstring (cmd[ size(cmd) -1 ]:"",",");
+ m["commands"] = maplist(string s, m["commands"]:[],{
+ return (substring(s,findfirstnotof(s," \t")));
+ });
+ m["comment"] = line[0]:"";
+
+ rules = add(rules,m);
+ break;
+
}
- });
+ }
});
- settings = filter(string k, list v, settings,{
- return (regexpmatch(k,".*_Alias"));
- });
+ y2milestone("user %1 host %2 runas %3 cmnd %4 def %5 rules %6", user_aliases2, host_aliases2, runas_aliases2, cmnd_aliases2, defaults, rules);
+
return true;
}
+
global boolean ReadLocalUsers() {
boolean current_progress = Progress::set(false);
boolean gui = Users::GetGUI ();
@@ -192,137 +192,79 @@
else return true;
}
-boolean WriteSudoSettings() {
- if (GetModified())
- {
- //Host aliases
- settings["Host_Alias"] = maplist (list <string> s, settings["Host_Alias"]:[],{
- if (haskey(host_aliases,s[1]:"")) {
- s[2] = mergestring(host_aliases[s[1]:""]:[],",");
- host_aliases = remove(host_aliases,s[1]:"");
- }
- else {
- s[1] = "";
- s[2] = "";
- }
- return s;
- });
-
- foreach(string opt_key, list<string> opt_val, host_aliases, {
- settings["Host_Alias"] = add(settings["Host_Alias"]:[], ["", opt_key, mergestring(opt_val,",")]);
- });
-
- //User aliases
- settings["User_Alias"] = maplist (list <string> s, settings["User_Alias"]:[],{
- if (haskey(user_aliases,s[1]:"")) {
- s[2] = mergestring(user_aliases[s[1]:""]:[],",");
- user_aliases = remove(user_aliases,s[1]:"");
- }
- else {
- s[1] = "";
- s[2] = "";
- }
- return s;
- });
-
- foreach(string opt_key, list<string> opt_val, user_aliases, {
- settings["User_Alias"] = add(settings["User_Alias"]:[], ["", opt_key, mergestring(opt_val,",")]);
- });
-
- //Runas aliases
- settings["Runas_Alias"] = maplist (list <string> s, settings["Runas_Alias"]:[],{
- if (haskey(runas_aliases,s[1]:"")) {
- s[2] = mergestring(runas_aliases[s[1]:""]:[],",");
- runas_aliases = remove(runas_aliases,s[1]:"");
- }
- else {
- s[1] = "";
- s[2] = "";
- }
- return s;
- });
-
- foreach(string opt_key, list<string> opt_val, runas_aliases, {
- settings["Runas_Alias"] = add(settings["Runas_Alias"]:[], ["", opt_key, mergestring(opt_val,",")]);
- });
-
- //Command Aliases
- settings["Cmnd_Alias"] = maplist (list <string> s, settings["Cmnd_Alias"]:[],{
- if (haskey(cmnd_aliases,s[1]:"")) {
- s[2] = mergestring(cmnd_aliases[s[1]:""]:[],",");
- cmnd_aliases = remove(cmnd_aliases,s[1]:"");
- }
- else {
- s[1] = "";
- s[2] = "";
- }
- return s;
- });
-
- foreach(string opt_key, list<string> opt_val, cmnd_aliases, {
- settings["Cmnd_Alias"] = add(settings["Cmnd_Alias"]:[], ["", opt_key, mergestring(opt_val,",")]);
- });
-
- //Restore defaults
- settings["Defaults"] = defaults;
+global boolean WriteSudoSettings2()
+{
+ list set = [];
+
+ foreach(map a, host_aliases2,{
+ list <string> line = [ a["c"]:"", "Host_Alias", a["name"]:"", mergestring(a["mem"]:[],",") ];
+ set = add(set, line);
+ });
+ foreach(map a, user_aliases2,{
+ list <string> line = [ a["c"]:"", "User_Alias", a["name"]:"", mergestring(a["mem"]:[],",")];
+ set = add(set, line);
+ });
+ foreach(map a, cmnd_aliases2,{
+ list <string> line = [ a["c"]:"", "Cmnd_Alias", a["name"]:"", mergestring(a["mem"]:[],",")];
+ set = add(set, line);
+ });
+ set = ( list < list <string> > ) merge(set, defaults);
+ foreach(map a, runas_aliases2,{
+ list <string> line = [ a["c"]:"", "Runas_Alias", a["name"]:"", mergestring(a["mem"]:[],",")];
+ set = add(set, line);
+ });
+
+ foreach(map m, rules,{
+ string user = (string) m["user"]:"";
+
+ user = mergestring (splitstring(user, "\\"), "\\\\");
+ string host = (string) m["host"]:"";
+ string comment = (string) m["comment"]:"";
+ string rest = (string) m["run_as"]:"" + " " + (( (boolean) m["no_passwd"]:false) ? "NOPASSWD: " : "") + mergestring((list <string>)m["commands"]:[],",");
- //Rest
- foreach(map m, user_specs,{
- string user = (string) m["user"]:"";
-
- user = mergestring (splitstring(user, "\\"), "\\\\");
- string host = (string) m["host"]:"";
- string comment = (string) m["comment"]:"";
- string rest = (string) m["run_as"]:"" + " " + (( (boolean) m["no_passwd"]:false) ? "NOPASSWD: " : "") + mergestring((list <string>)m["commands"]:[],",");
+ set = add(set,[comment, user, host, rest]);
+ });
- if( !contains(settings[user]:[], [comment, host, rest]) )
- settings[user] = add(settings[user]:[],[comment, host, rest]);
- });
+ y2milestone("Sudo settings %1", set);
- foreach(string key, list value, settings, {
- if ( deleted_specs != [] && contains(deleted_specs, key)){
- settings = remove(settings, key);
- }
- });
+ if (SCR::Write(.sudo, set))
+ return SCR::Write(.sudo, nil);
+ return true;
+}
- y2milestone("Writing sudo settings %1", settings);
+integer citem = -1;
- if (SCR::Write(.sudo, settings))
- return SCR::Write(.sudo, nil);
- else return false;
- }
- return true;
+global void SetItem( integer i )
+{
+ y2internal("Current item %1", i);
+ citem = i;
}
-global list