ACC SHELL

Path : /usr/share/YaST2/modules/
File Upload :
Current File : //usr/share/YaST2/modules/Sudo.ycp

/* ------------------------------------------------------------------------------
 * Copyright (c) 2006 Novell, Inc. All Rights Reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of version 2 of the GNU General Public License as published by the
 * Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, contact Novell, Inc.
 *
 * To contact Novell about this file by physical or electronic mail, you may find
 * current contact information at www.novell.com.
 * ------------------------------------------------------------------------------
 */

/**
 * File:	modules/Sudo.ycp
 * Package:	Configuration of sudo
 * Summary:	Sudo settings, input and output functions
 * Authors:	Bubli <kmachalkova@suse.cz>
 *
 * $Id: Sudo.ycp 27914 2006-02-13 14:32:08Z locilka $
 *
 * Representation of the configuration of sudo.
 * Input and output routines.
 */

{

module "Sudo";
textdomain "sudo";

import "Confirm";
import "Map";
import "Message";
import "Progress";
import "Report";
import "Popup";
import "Service";
import "SCR";
import "String";
import "Summary";
import "UsersPasswd";

/**
 * Data was modified?
 */
boolean modified = false;

integer sl = 10;
/**
 * Data was modified?
 * @return true if modified
 */
global boolean GetModified() {
    return modified;
}

global void SetModified() {
    modified = true;
}

global string ValidCharsUsername = deletechars (String::CGraph (), "'\"") + " ";

list < list <any> >  settings2 = [];
list< map <string, any> > host_aliases2 = [];
list< map <string, any> > user_aliases2 = [];
list< map <string, any> > cmnd_aliases2 = [];
list< map <string, any> > runas_aliases2 = [];
list < list <any> > defaults = [];
list < map <string, any> > rules = [];
global list <string> all_users = [];

boolean ReadSudoSettings2() {
	settings2 = ( list < list <any> >)SCR::Read(.sudo);
	y2milestone("Sudo settings %1", settings2);

	foreach( list 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;
		}
		//rules + defaults remained
		default: {
		    if ( regexpmatch(type, "^Defaults.*$") ) {
		       //do nothing, keep defaults untouched
		        defaults = add(defaults,line);
		    }
		    else {
			map <string, any> 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 (regexpmatch(line[3]:"","NOPASSWD:|SETENV:|NOEXEC:")){
			    m["tag"] = regexpsub(line[3]:"", "(NOPASSWD:|SETENV:|NOEXEC:)","\\1");
			}

			/*if(issubstring(line[3]:"","NOPASSWD:")) {
				m["no_passwd"] = (boolean) true;
			}
			else {
			     m["no_passwd"] = (boolean) false;
			}*/

			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;
	
			}
		    }
		}
	});

	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() {

	if (!UsersPasswd::Read( $[]))
	    return false;

	list <string> users = (list<string>) merge (
	      Map::Keys( UsersPasswd::GetUsers("local")),
	      Map::Keys( UsersPasswd::GetUsers("system")) );

	list <string> available_groups = (list<string>) merge (
	      Map::Keys( UsersPasswd::GetGroups("local")),
	      Map::Keys( UsersPasswd::GetGroups("system")) );

        available_groups = maplist (string group, available_groups, {
	    return ("%" + group);
	});

	all_users = (list <string>) merge(users,available_groups);
	y2milestone("Read the following users and groups: %1", all_users);

	return true;
}

global boolean WriteSudoSettings2()
{
    list <list <any> > set = [];

    foreach(map <string, any> a, host_aliases2,{
	list <string> line = [ a["c"]:"", "Host_Alias", a["name"]:"", mergestring(a["mem"]:[],",") ];
	set = add(set, line);
    });
    foreach(map <string, any> a, user_aliases2,{
	list <string> line = [ a["c"]:"", "User_Alias", a["name"]:"", mergestring(a["mem"]:[],",")];
	set = add(set, line);
    });
    foreach(map <string, any> a, cmnd_aliases2,{
	list <string> line = [ a["c"]:"", "Cmnd_Alias", a["name"]:"", mergestring(a["mem"]:[],",")];
	set = add(set, line);
    });

    set = ( list < list <any> > ) merge(set, defaults);

    foreach(map <string, any> a, runas_aliases2,{
	list <string> line = [ a["c"]:"", "Runas_Alias", a["name"]:"", mergestring(a["mem"]:[],",")];
	set = add(set, line);
    });

    foreach(map <string, any> 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"]:"" + " " + (string) m["tag"]:"" + mergestring((list <string>)m["commands"]:[],",");

	set = add(set,[comment, user, host, rest]);
    });

    y2milestone("Sudo settings %1", set);

    if (SCR::Write(.sudo, set))
	return SCR::Write(.sudo, nil);
    return true;
}

integer citem = -1;

global void SetItem( integer i )
{
    y2internal("Current item %1", i);
    citem = i;
}

global integer GetItem()
{
    return citem;
}

global list <map <string, any> > GetRules(){
	return rules;
}

global void RemoveRule( integer i ) {
	rules = remove( rules, i);
}

global map <string, any> GetRule(integer i) {
	return rules[i]:$[];
}

global void SetRule(integer i, map <string,any> spec) {
	rules[i] = spec;
}

global boolean SearchRules(string what, string key) {
	boolean found = false;

	foreach (map <string, any> m, rules, {
		if (haskey(m, what)) {
			if (what == "commands") {
				if (contains(m[what]:[], key)){
					found = true;
					break;
				}
			} else {
				if (m[what]:"" == key) {
					found = true;
					break;
				}
			}
		}
	});

	return found;
}

global boolean SystemRulePopup(map <string, any> m, boolean delete) {
	if ( m["user"]:"" == "ALL" && 
	     m["host"]:"" == "ALL" && 
	     m["run_as"]:"" == "(ALL)") {

		string text = _("This rule is a system rule necessary for correct functionality of sudo.\n");

		if (delete) {
			text = text + _("After deleting it, some applications may no longer work.\nReally delete?");
		}
		else {
			text = text + _("If you change it, some applications may no longer work.\nReally edit? ");
		}

		return (Popup::YesNo(text));
	}
	else return true;
}


global list <string> GetAliasNames (string what) {
	list <string> ret = [];
	switch(what) {
		case ("user"): 
			ret = maplist ( map <string, any> m, user_aliases2,
			        { return  m["name"]:""; 
			    });
			break;
		case ("run_as"): 
			ret = maplist ( map <string, any> m, runas_aliases2,
			        { return  m["name"]:""; 
			    });
			break;
		case ("host"): 
			ret = maplist ( map <string, any> m, host_aliases2,
			        { return  m["name"]:""; 
			    });
			break;
		case ("command"):
			ret = maplist ( map <string, any> m, cmnd_aliases2,
			        { return  m["name"]:""; 
			    });
			break;
		default: return [];
	}
	return ret;
}

global boolean SearchAlias2(string name, list < map <string, any> > aliases ) {
    list < map <string, any> > tmp  = [];
    tmp = filter( map <string, any> m, aliases, {
	return (m["name"]:"" == name);
    });

   return ( size(tmp) > 0 );
}


/* Users */
global list < map <string, any> > GetUserAliases2() {
    return user_aliases2;
}

global void SetUserAlias(integer i, map <string,any> alias ) {
	user_aliases2[i] = alias;
}

global void RemoveUserAlias2( integer i) {
	user_aliases2 = remove(user_aliases2, i);
}

/* end Users */

/* Hosts */
global list < map <string, any> > GetHostAliases2() {
    return host_aliases2;
}

global void RemoveHostAlias2( integer i) {
	host_aliases2 = remove(host_aliases2, i);
}

global void SetHostAlias(integer i, map <string,any> alias) {
	host_aliases2[i] = alias;
}
/* end Hosts */

/* RunAs */
global list < map <string, any> > GetRunAsAliases2() {
	return runas_aliases2;
}

global void RemoveRunAsAlias2( integer i) {
	runas_aliases2 = remove(runas_aliases2, i);
}

global void SetRunAsAlias(integer i, map <string,any> alias) {
	runas_aliases2[i] = alias;
}

/* end RunAs */

/* Commands */
global list < map <string, any> > GetCmndAliases2() {
	return cmnd_aliases2;
}

global void SetCmndAlias(integer i, map <string,any> alias) {
	cmnd_aliases2[i] = alias;
}

global void RemoveCmndAlias2( integer i) {
	cmnd_aliases2 = remove(cmnd_aliases2, i);
}

/*end Commands */

global boolean Abort() {
	if (Sudo::GetModified())
	{
	    return Popup::YesNo( _("All changes will be lost. Really quit sudo configuration without saving ?"));
	}
	else
	    return true;
}

/**
 * Checks whether an Abort button has been pressed.
 * If so, calls function to confirm the abort call.
 :*
 * @return boolean true if abort confirmed
 */
global boolean PollAbort() {
    if (UI::PollInput() == `abort)
	return Abort();

    return false;
}

/**
 * Read all sudo settings
 * @return true on success
 */
global boolean Read() {

    if (!Confirm::MustBeRoot())
	return false;

    if(!ReadSudoSettings2()) 
	Report::Error(Message::CannotReadCurrentSettings());

    /* Error message */
    if(!ReadLocalUsers())
	Report::Error(_("An error occurred while reading users and groups."));

    /* Sudo read dialog caption
    string caption = _("Initializing sudo Configuration");

    integer steps = 2;

    Progress::New( caption, " ", steps, [
	    /* Progress stage 1/2
	    _("Read sudo settings"),
	    /* Progress stage 2/2
	    _("Read local users and groups")
	], [
	    /* Progress step 1/2
	    _("Reading sudo settings..."),
	    /* Progress step 2/2
	    _("Reading local users and groups..."),
	    /* Progress finished
	    Message::Finished()
	],
	""
    );*/

    modified = false;
    return true;
}

/**
 * Write all sudo settings
 * @return true on success
 */
global boolean Write() {

    /* Sudo read dialog caption */
    string caption = _("Saving sudo Configuration");

    integer steps = 1;

    integer sl = 500;

    boolean ret = true;

    // We do not set help text here, because it was set outside
    Progress::New(caption, " ", steps, [
	    /* Progress stage 1/1 */
	    _("Write the settings"),
	], [
	    /* Progress step 1/1 */
	    _("Writing the settings..."),
	    /* Progress finished */
	    Message::Finished()
	],
	""
    );

    sleep(sl);

    // write settings
    if(PollAbort()) return false;
    Progress::NextStage();
    /* Error message */
    if(!WriteSudoSettings2()) {
	Report::Error (_("Cannot write settings."));
	ret = false;
    }
    sleep(sl);

    Progress::NextStage();
    sleep(sl);

    return ret;
}


/* EOF */
}

ACC SHELL 2018