ACC SHELL
/**
* File:
* modules/Nis.ycp
*
* Module:
* Configuration of NIS client
*
* Summary:
* NIS client configuration data, I/O functions.
*
* Authors:
* Jan Holesovsky <kendy@suse.cz>
* Dan Vesely <dan@suse.cz>
* Martin Vidner <mvidner@suse.cz>
*
* $Id: Nis.ycp 57495 2009-06-08 13:06:03Z jsuchome $
*
*/
{
module "Nis";
textdomain "nis";
import "Address";
import "Autologin";
import "IP";
import "Message";
import "Nsswitch";
import "Package";
import "Progress";
import "Report";
import "Service";
import "Summary";
import "SuSEFirewall";
import "Wizard";
/* default value of settings modified */
global boolean modified = false;
/**
* Function sets internal variable, which indicates, that any
* settings were modified, to "true"
*/
global define void SetModified () {
modified = true;
}
/**
* Functions which returns if the settings were modified
* @return boolean settings were modified
*/
global define boolean GetModified () {
return modified;
}
/**
* Required packages for this module to operate
*
*/
global list<string> required_packages = ["ypbind"];
/**
* Should ypbind be started at boot?
* If not, other settings are not touched.
*/
global boolean start = false;
/**
* IP addresses of NIS servers.
*/
global list <string> servers = [];
/**
* @return Access the servers as a string
*/
global string GetServers () {
return mergestring (servers, " ");
}
/**
* Set the servers from a string
* @param servers_s a whitespace separated list
*/
global void SetServers (string servers_s) {
servers = filter (string s, splitstring (servers_s, " \t"),``(s != ""));
}
/**
* Broadcast for the default domain?
* (New in ypbind-1.12)
*/
global boolean default_broadcast = false;
/**
* Servers for a multiple-domain configuration.
* Keys are domains, values are lists of servers (strings).
* The domains must be the same as for multidomain_broadcast
* @see multidomain_broadcast
*/
global map<string,list> multidomain_servers = $[];
/**
* Servers for a multiple-domain configuration.
* Whether a broadcast will be done if the servers don't respond.
* Keys are domains, values are booleans.
* The domains must be the same as for multidomain_servers
* @see multidomain_servers
* @see global_broadcast
*/
global map<string,boolean> multidomain_broadcast = $[];
/**
* If this option is set, ypbind will ignore /etc/yp.conf and use
* a broadcast call to find a NIS server in the local subnet. You
* should avoid to use this, it is a big security risk.
* @see multidomain_broadcast
* @see default_broadcast
*/
global boolean global_broadcast = false;
global map slp_domain = $[];
// netconfig policy
global string policy = "auto";
// which service mapper is used (rpcbind/portmap)
string rpc_mapper = "rpcbind";
string domain = "";
string old_domain = nil;
boolean domain_changed = false;
list<string> static_keylist = [];
/**
* Read Netconfig configuration
*/
global void getNetconfigValues() {
y2milestone("getNetconfigValues called");
// reset the values
multidomain_servers = $[];
multidomain_broadcast = $[];
slp_domain = $[];
servers = [];
policy = (string)SCR::Read(.sysconfig.network.config.NETCONFIG_NIS_POLICY);
y2milestone("policy : %1", policy);
if (policy == nil) policy = "";
map<string, map<string, string> > staticVals = $[];
list<string> keylist = SCR::Dir (.sysconfig.network.config);
y2milestone("KEYLIST: %1", keylist);
if (keylist == nil) keylist = [];
foreach (string key, keylist, {
if (!issubstring(key, "NETCONFIG_NIS_STATIC_DOMAIN") &&
!issubstring(key, "NETCONFIG_NIS_STATIC_SERVERS"))
continue;
string value =(string)SCR::Read(add(.sysconfig.network.config,key));
y2milestone("Found %1 = %2", key, value);
string num = "";
if (key == "NETCONFIG_NIS_STATIC_DOMAIN")
{
staticVals["0"] = add (staticVals["0"]:$[], "DOMAIN", value);
}
else if (key == "NETCONFIG_NIS_STATIC_SERVERS")
{
staticVals["0"] = add (staticVals["0"]:$[], "SERVERS", value);
}
else
{
static_keylist = add (static_keylist, key);
num = regexpsub(key, "^NETCONFIG_NIS_STATIC_(DOMAIN|SERVERS)_(.*)", "\\2");
y2milestone("try to get the number: %1", num);
if (issubstring(key, "NETCONFIG_NIS_STATIC_DOMAIN"))
{
staticVals[num] = add(staticVals[num]:$[], "DOMAIN", value); }
else if (issubstring(key, "NETCONFIG_NIS_STATIC_SERVERS"))
{
staticVals[num] = add(staticVals[num]:$[], "SERVERS",value);
}
}
});
y2milestone("STATIC VALS: %1", staticVals);
foreach (string key, map<string, string> value, staticVals, {
if (value["DOMAIN"]:nil == "")
{
if (value["SERVERS"]:"" != "")
{
string sr = GetServers() + " " + value["SERVERS"]:"";
SetServers (sr);
}
}
else if (value["DOMAIN"]:nil == "broadcast")
{
global_broadcast = true;
}
else if (value["DOMAIN"]:"" != "")
{
if (value["SERVERS"]:nil == "broadcast")
{
if (key == "0")
{
default_broadcast = true;
}
multidomain_broadcast[value["DOMAIN"]:""] = true;
}
else if (value["SERVERS"]:nil == "slp")
{
slp_domain[value["DOMAIN"]:""] = true;
}
else if (value["SERVERS"]:"" != "")
{
multidomain_servers[value["DOMAIN"]:""] =
splitstring (value["SERVERS"]:"", " ");
}
}
});
foreach (string domain, list value, multidomain_servers, {
if (!haskey (multidomain_broadcast, domain))
{
multidomain_broadcast[domain] = false;
}
});
foreach (string domain, boolean value, multidomain_broadcast, {
if (!haskey(multidomain_servers, domain))
{
multidomain_servers [domain] = [];
}
});
foreach (string domain, any value, (map<string,any>) slp_domain, {
if (!haskey (multidomain_servers, domain))
{
multidomain_servers[domain] = [];
}
});
y2milestone("Servers: %1", servers);
y2milestone("multidomain_servers: %1", multidomain_servers);
y2milestone("multidomain_broadcast: %1", multidomain_broadcast);
y2milestone("slp_domain: %1", slp_domain);
y2milestone("default_broadcast: %1", default_broadcast);
}
/**
* Write the netconfig configuration
*/
global boolean setNetconfigValues() {
SCR::Write(.sysconfig.network.config.NETCONFIG_NIS_POLICY, policy);
foreach (string domain, list value, multidomain_servers, {
if (!haskey (multidomain_broadcast, domain))
{
multidomain_broadcast[domain] = false;
}
});
foreach (string domain, boolean value, multidomain_broadcast, {
if (!haskey (multidomain_servers, domain))
{
multidomain_servers[domain] = [];
}
});
foreach (string domain, any value, (map<string, any>) slp_domain, {
if (!haskey (multidomain_servers, domain))
{
multidomain_servers[domain] = [];
}
});
foreach (string key, static_keylist, {
y2milestone("Remove : %1", key);
SCR::Write (add (.sysconfig.network.config, key), nil);
});
/* remove the content of this */
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN, "");
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS, "");
y2milestone("Servers: %1", servers);
y2milestone("multidomain_servers: %1", multidomain_servers);
y2milestone("multidomain_broadcast: %1", multidomain_broadcast);
y2milestone("slp_domain: %1", slp_domain);
y2milestone("default_broadcast: %1", default_broadcast);
integer cnt = 0;
if (size (servers) > 0)
{
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN,
"");
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS,
mergestring (servers, " "));
cnt = cnt + 1;
}
foreach (string dom, list<string> srvs, (map<string,list<string> >)
multidomain_servers,
{
if (dom == "") continue;
if (size(srvs) > 0)
{
if (cnt == 0)
{
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN, dom);
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS, mergestring (srvs, " "));
}
else
{
SCR::Write (add (.sysconfig.network.config, "NETCONFIG_NIS_STATIC_DOMAIN_"+cnt), dom);
SCR::Write (add (.sysconfig.network.config, "NETCONFIG_NIS_STATIC_SERVERS_"+cnt), mergestring(srvs, " "));
}
cnt = cnt + 1;
}
if (multidomain_broadcast[dom]:false == true)
{
if (cnt == 0)
{
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN, dom);
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS, "broadcast");
}
else
{
SCR::Write (add (.sysconfig.network.config, "NETCONFIG_NIS_STATIC_DOMAIN_"+cnt), dom);
SCR::Write (add (.sysconfig.network.config, "NETCONFIG_NIS_STATIC_SERVERS_"+cnt), "broadcast");
}
cnt = cnt + 1;
}
if (slp_domain[dom]:false == true)
{
if (cnt == 0)
{
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN, dom);
SCR::Write(.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS, "slp");
}
else
{
SCR::Write(add(.sysconfig.network.config, "NETCONFIG_NIS_STATIC_DOMAIN_"+cnt), dom);
SCR::Write(add(.sysconfig.network.config, "NETCONFIG_NIS_STATIC_SERVERS_"+cnt), "slp");
}
cnt = cnt + 1;
}
});
if (default_broadcast == true)
{
if (cnt == 0)
{
SCR::Write(.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN, domain);
SCR::Write(.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS, "broadcast");
}
else
{
SCR::Write(add(.sysconfig.network.config, "NETCONFIG_NIS_STATIC_DOMAIN_"+cnt), domain);
SCR::Write(add(.sysconfig.network.config, "NETCONFIG_NIS_STATIC_SERVERS_"+cnt), "broadcast");
}
cnt = cnt + 1;
}
else if (global_broadcast == true)
{
if (cnt == 0)
{
SCR::Write(.sysconfig.network.config.NETCONFIG_NIS_STATIC_DOMAIN, "broadcast");
SCR::Write(.sysconfig.network.config.NETCONFIG_NIS_STATIC_SERVERS, "");
}
else
{
SCR::Write(add(.sysconfig.network.config, "NETCONFIG_NIS_STATIC_DOMAIN_"+cnt), "broadcast");
SCR::Write(add(.sysconfig.network.config, "NETCONFIG_NIS_STATIC_SERVERS_"+cnt), "");
}
cnt = cnt + 1;
}
if (! SCR::Write(.sysconfig.network.config, nil))
{
Report::Error (Message::ErrorWritingFile ("/etc/sysconfig/network/config"));
return false;
}
return true;
}
/**
* If the domain has changed from a nonempty one, it may only be
* changed at boot time. Use this to warn the user.
* @return whether changed by SetDomain
*/
global define boolean DomainChanged () ``{
return domain_changed;
}
/**
* @return Get the NIS domain.
*/
global define string GetDomain () ``{
return domain;
}
/**
* Set the NIS domain.
* @param new_domain a new domain
*/
global define void SetDomain (string new_domain) ``{
domain = new_domain;
if (domain != old_domain && old_domain != "")
{
domain_changed = true;
}
}
// DHCP cooperation
/**
* #35654: if the server is running and sysconfig wants NIS data,
* it's ok to FitIntoSingle
*/
global boolean dhcpcd_running = false;
/**
* If dhcp_wanted changes, we need to restart the DHCP client
*/
global boolean dhcp_restart = false;
// The following four are from sysconfig/ypbind; the comments are
// taken from there. The dialog help texts have "user friendlier"
// descriptions.
/**
* If this option is set, ypbind will only bind to the loopback
* interface and remote hosts cannot query it.
*/
global boolean local_only = false;
/**
* You should set this to "yes" if you have a NIS server in your
* network, which binds only to high ports over 1024. Since this
* is a security risk, you should consider to replace the NIS
* server with another implementation.
*/
global boolean broken_server = false;
/**
* Extra options for ypbind. Here you can add options like
* "-ypset", "-ypsetme", "-p port" or "-no-ping".
*/
global string options = "";
/**
* If no, automounter will not be affected.
*/
global boolean _autofs_allowed = true;
/**
* Start automounter and import the settings from NIS. (Bug 6092)
*/
global boolean _start_autofs = false;
/**
* Output of "rcypbind start", if there was an error.
* Read only.
* This is currently used only in nis-server for its more advanced
* error reporting. (Bug 14706)
*/
global string YpbindErrors = "";
/* ---------------------------------------------------------------- */
// used also for nis-server
/**
* Check syntax of a NIS domain name
* @param domain a domain name
* @return true if correct
*/
global define boolean check_nisdomainname (string domain) ``{
// TODO
// disallow whitespace and special characters...
return domain != "" && domain != "(none)" && size (domain) <= 64;
}
/**
* @return describe a valid NIS domain name
*/
global define string valid_nisdomainname () ``{
// Translators: do not translate (none)!
return _("A NIS domain name must not be empty,
it must not be \"(none)\",
and it must be at most 64 characters long.
");
}
/**
* If the hostname resolution is done over NIS,
* names cannot be used to specify servers.
*/
boolean hosts_by_nis = false;
/**
* Using NIS and LDAP simultaneously is not supported (#36981).
*/
boolean users_by_ldap = false;
/**
* Used in the UI when NIS is turned on.
*/
global define boolean UsersByLdap () ``{
return users_by_ldap;
}
/**
* Describe a valid address - ip4 or name, names only if
* nsswitch.conf does not have hosts: nis
* @return a description
*/
global define string valid_address_nis () ``{
y2debug ("hosts_by_nis %1", hosts_by_nis);
if (hosts_by_nis)
{
// message popup
return _("Only an IP address can be used
because host names are resolved using NIS.\n\n") + IP::Valid4();
}
else
{
return Address::Valid4();
}
}
/**
* Check syntax of a network address (ip4 or name), names only if
* nsswitch.conf does not have hosts: nis
* @param a an address
* @return true if correct
*/
global define boolean check_address_nis (string a) ``{
y2debug ("hosts_by_nis %1", hosts_by_nis);
if (hosts_by_nis)
{
return IP::Check4(a);
}
else
{
return Address::Check(a);
}
}
/* ---------------------------------------------------------------- */
/**
* Has the configuration been changed?
* Can be used as an argument to Popup::ReallyAbort
*/
global boolean touched = false;
/**
* A convenient shortcut for setting touched.
* @param really if true, set Nis::touched
* @example Nis::Touch (Nis::var != ui_var);
*/
global define void Touch (boolean really) ``{
touched = touched || really;
}
/* ---------------------------------------------------------------- */
/**
* Read only, set by ProbePackages.
* Use as an argument to DoInstallAndRemove
*/
global list<string> install_packages = [];
/**
* Detect which packages have to be installed
* and return a descriptive string for a plain text pop-up.
* @return "" or "Foo will be installed.\nBar will be installed.\n"
*/
global define string ProbePackages () {
string message = "";
install_packages = [];
if (_autofs_allowed && _start_autofs)
{
if (! Package::Installed ("autofs"))
{
install_packages = add (install_packages, "autofs");
// Translators: popup message part, ends with a newline
message = message + _("The automounter package will be installed.\n");
}
if (!Package::Installed ("nfs-client"))
install_packages = add (install_packages, "nfs-client");
}
return message;
}
/* ---------------------------------------------------------------- */
/**
* Set module data
* @return void
*/
global define void Set (map settings) ``{
start = settings["start_nis"]:false;
servers = settings["nis_servers"]:[];
default_broadcast = settings["nis_broadcast"]:false;
domain = settings["nis_domain"]:"";
old_domain = domain;
// we don't know what the state will be before Write, so restart it
dhcp_restart = true;
list<map> other_domains = settings["nis_other_domains"]:[];
foreach (map other_domain, other_domains, ``{
string domain = other_domain["nis_domain"]:"";
list<string> servers = other_domain["nis_servers"]:[];
boolean b = other_domain["nis_broadcast"]:false;
multidomain_servers[domain] = servers;
multidomain_broadcast[domain] = b;
});
local_only = settings["nis_local_only"]:false;
broken_server = settings["nis_broken_server"]:false;
options = settings["nis_options"]:"";
// autofs is not touched in Write if the map does not want it
_autofs_allowed = haskey (settings, "start_autofs");
_start_autofs = settings["start_autofs"]:false;
if (_start_autofs)
required_packages = (list <string>)
union (required_packages, ["autofs", "nfs-client"]);
policy = settings["netconfig_policy"]:policy;
slp_domain = settings["slp_domain"]:slp_domain;
touched = true;
}
// TODO update the map keys
// better still: link to a current interface description
/**
* Get all the NIS configuration from a map.
* When called by nis_auto (preparing autoinstallation data)
* the map may be empty.
* @param settings $["start": "domain": "servers":[...] ]
* @return success
*/
global define boolean Import (map settings) ``{
if (size (settings) == 0)
{
//Provide defaults for autoinstallation editing:
//Leave empty.
old_domain = domain;
// enable _autofs_allowed
// Injecting it into the defaults for the GUI
// but leaving the check in Set makes it possible
// to delete the element manually from the xml profile
// and leave autofs untouched
settings["start_autofs"] = false;
Set(settings);
return true;
}
boolean missing = false;
// "nis_domain" can be omitted if nis_by_dhcp is true
foreach (string k, ["start_nis"], ``{
if (! haskey (settings, k))
{
y2error ("Missing at Import: '%1'.", k);
missing = true;
}
});
if (missing)
{
return false;
}
Set(settings);
return true;
}
// TODO update the map keys
// better still: link to a current interface description
/**
* Dump the NIS settings to a map, for autoinstallation use.
* @return $["start":, "servers":[...], "domain":]
*/
global define map Export () {
list other_domains = maplist (string d, list s, multidomain_servers, {
return $[
"nis_domain": d,
"nis_servers": s,
"nis_broadcast": multidomain_broadcast[d]:false,
];
});
if (global_broadcast)
{
y2error ("Attempt to export Nis::global_broadcast");
}
return $[
"start_nis": start,
"nis_servers": servers,
"nis_domain": domain,
"nis_broadcast": default_broadcast,
"nis_other_domains": other_domains,
"nis_local_only": local_only,
"nis_broken_server": broken_server,
"nis_options": options,
"start_autofs": _start_autofs,
"slp_domain" : slp_domain,
"netconfig_policy" : policy,
];
}
// copied from Mail.ycp
// replace with a custom list
/**
* Summarizes a list of data
* @param title passed to Summary::AddHeader
* @param value a list (of scalars, lists or maps)
* @return Summary-formatted description
*/
define string ListItem(string title, any value) ``{
string summary = "";
summary = Summary::AddHeader(summary, title);
//enhancement BEGIN
if (is (value, map))
{
value = maplist (any k, any v, (map) value, ``(k));
}
//enhancement END
if (is(value,list) && size((list) value)>0) {
summary = Summary::OpenList(summary);
foreach (any d, (list) value, ``{
string entry = "";
if (is(d,map) || is (d,list))
entry = sformat("%1 Entries configured", is(d, map) ? size((map) value) : size((list) value));
else
entry = (string) d;
summary = Summary::AddListItem(summary, entry);
});
summary = Summary::CloseList(summary);
} else {
summary = Summary::AddLine(summary,Summary::NotConfigured ());
}
return summary;
}
/**
* @return Html formatted configuration summary
*/
global define string Summary () ``{
// TODO multidomain_servers, multidomain_broadcast
// OK, a dumb mapping is possible, but wouldn't it be
// too complicated to write by hand?
string summary = "";
string nc = Summary::NotConfigured ();
// summary: Domain or servers are retrieved by the
// Dynamic Host Configuration Protocol.
// Will be placed after NIS Domain/NIS Servers instead of the
// actual settings.
string dhcp = _("by DHCP");
// summary header
summary = Summary::AddHeader(summary, _("NIS Client enabled"));
// summary item: an option is turned on
summary = Summary::AddLine(summary, (start) ? _("Yes") : nc);
// summary header
summary = Summary::AddHeader(summary, _("NIS Domain"));
summary = Summary::AddLine(summary,((domain != "") ? domain : nc));
// summary header
summary = Summary::AddHeader(summary, _("NIS Servers"));
summary = Summary::AddLine(summary, ((servers !=[]) ? mergestring(servers,"<br>") : nc));
// summary header
summary = Summary::AddHeader(summary, _("Broadcast"));
// summary item: an option is turned on
summary = Summary::AddLine(summary, (default_broadcast) ? _("Yes") : nc);
// TODO: a full list
summary = summary + ListItem (_("Other domains"), multidomain_servers);
// summary header
summary = Summary::AddHeader(summary, _("Answer to local host only"));
// summary item: an option is turned on
summary = Summary::AddLine(summary, (local_only) ? _("Yes") : nc);
// summary header
summary = Summary::AddHeader(summary, _("Broken server"));
// summary item: an option is turned on
summary = Summary::AddLine(summary, (broken_server) ? _("Yes") : nc);
// summary header
summary = Summary::AddHeader(summary, _("ypbind options"));
summary = Summary::AddLine(summary, (options!="") ? options : nc);
// summary header
summary = Summary::AddHeader(summary, _("Automounter enabled"));
// summary item: an option is turned on
summary = Summary::AddLine(summary, (_start_autofs) ? _("Yes") : nc);
return summary;
}
/**
* Makes an item for the short summary. I guess the users module
* wants to avoid paragraph breaks.
* @param title
* @param value
* @return [b]title[/b]: value[br]
*/
global define string BrItem (string title, string value) ``{
return sformat ("<b>%1</b>: %2<br>", title, value);
}
/**
* Create a short textual summary with configuration abstract
* It is called by "authentication/user sources" dialog in yast2-users
* @return summary of the current configuration
*/
global define string ShortSummary() ``{
string summary = "";
string nc = Summary::NotConfigured ();
summary =
// summary item
BrItem (_("Servers"), ((servers !=[]) ? GetServers() : nc)) +
// summary item
BrItem (_("Domain"), ((domain != "") ? domain : nc)) +
// summary item (yes/no follows)
BrItem (_("Client Enabled"), start ? _("Yes"): _("No"));
return summary;
}
/**
* Reads NIS settings from the SCR
* @return success
*/
global define boolean Read () ``{
start = Service::Enabled("ypbind");
getNetconfigValues();
if (servers == nil) servers = [];
if (default_broadcast == nil) default_broadcast = false;
if (multidomain_servers == nil) multidomain_servers = $[];
if (multidomain_broadcast == nil) multidomain_broadcast = $[];
if (slp_domain == nil) slp_domain = $[];
map out = (map) SCR::Execute (.target.bash_output, "/bin/ypdomainname");
domain = deletechars (out["stdout"]:"", "\n");
old_domain = domain;
dhcpcd_running =
SCR::Execute (.target.bash, "ls /var/run/dhcpcd-*.pid") == 0;
local_only = SCR::Read (.sysconfig.ypbind.YPBIND_LOCAL_ONLY) == "yes";
global_broadcast = SCR::Read (.sysconfig.ypbind.YPBIND_BROADCAST) == "yes";
broken_server = SCR::Read (.sysconfig.ypbind.YPBIND_BROKEN_SERVER) == "yes";
options = (string) SCR::Read (.sysconfig.ypbind.YPBIND_OPTIONS);
// install on demand
_start_autofs = _autofs_allowed && Service::Enabled("autofs");
hosts_by_nis = contains (Nsswitch::ReadDb ("hosts"), "nis");
list<string> nss_passwd = Nsswitch::ReadDb ("passwd");
users_by_ldap =
contains (nss_passwd, "ldap") ||
(contains (nss_passwd, "compat") &&
contains (Nsswitch::ReadDb ("passwd_compat"), "ldap"));
Autologin::Read ();
boolean progress_orig = Progress::set (false);
SuSEFirewall::Read ();
Progress::set (progress_orig);
return true;
}
/**
* Make up data for screnshots.
* To be used instead of @ref Read .
*/
global define void Fake () ``{
y2milestone ("Faking data for screenshots");
start = true;
servers = ["10.42.0.1"];
default_broadcast = false;
multidomain_servers = $[
"printer.example.com": [],
"test.example.com": ["10.42.1.1", "10.42.1.2"],
];
multidomain_broadcast = $[
"printer.example.com": true,
"test.example.com": false,
];
domain = "example.com";
old_domain = domain;
local_only = false;
global_broadcast = false;
broken_server = false;
options = "";
_autofs_allowed = true;
_start_autofs = true;
hosts_by_nis = false;
}
/**
* @param file a pathname
* @return is there a nis inclusion?
*/
define boolean HasPlus (string file) ``{
// does the file have a plus?
y2milestone("file %1 has pluses", file);
return (0 == SCR::Execute (.target.bash, "/usr/bin/grep -q '^[+-]' " + file));
}
/**
* If a file does not contain a NIS entry, add it.
* @param file pathname
* @param what a "+" line without a '\n'
* @return success?
*/
define boolean WritePlusesTo (string file, string what) ``{
boolean ok = true;
if (!HasPlus (file))
{
// backup the file:
SCR::Execute (.target.bash,sformat("/bin/cp %1 %1.YaST2save",file));
if (SCR::Execute (.target.bash, sformat ("/bin/echo '%1' >> %2", what, file)) != 0)
{
ok = false;
}
}
// TODO only for passwd?
// replace the 'nologin' occurence (#40571)
else if (SCR::Execute (.target.bash, sformat ("/bin/grep -q '^%1/sbin/nologin' %2", what, file)) == 0)
{
ok = SCR::Execute (.target.bash, sformat ("/usr/bin/sed -i.YaST2save -e 's@%1/sbin/nologin@%1@' %2", what, file)) == 0;
}
if (!ok)
{
Report::Error (Message::ErrorWritingFile (file));
}
return ok;
}
/**
* Do we need compat? Is there a plus in any of the user databases?
* @return true/false
*/
define boolean HavePlus () ``{
list<string> files = [
"/etc/passwd",
"/etc/shadow",
"/etc/group",
];
// find a file having a plus
return nil != find (string file, files, ``( HasPlus (file) ));
}
/**
* Add "+" lines to system files so that NIS entries get merged in.
* (Formerly this was done in SuSEconfig.ypclient)
* @return success?
*/
define boolean WritePluses () ``{
list<string> files = ["passwd", "shadow", "group"];
//don't forget a newline
map what_to_write = $[
"passwd": "+::::::",
"group": "+:::",
"shadow": "+",
];
foreach (string f, files, {
y2milestone("Writing pluses to %1", f);
if (! WritePlusesTo (sformat ("/etc/%1", f), what_to_write[f]:""))
{
return false;
}
});
return true;
}
/**
* Configures the name service switch for the user databases
* according to chosen settings
* @return success?
*/
global define boolean WriteNssConf () {
list<string> dbs = ["passwd", "group", "shadow"];
list<string> nis_dbs = [ "services" ,"netgroup", "aliases" ];
// Why bother with both compat and nis?
// If there's no plus, we don't have to write passwd etc.
// And it's supposed to be faster.
// But then programs have to reread nsswitch :( #23203
// so we stick with compat.
if (start)
{
// we want to switch to "compat"
foreach (string db, dbs, ``{
// what if a db is not mentioned?
// We get [] meaning compat, so it's ok to make it explicit
list<string> db_l = Nsswitch::ReadDb (db);
if (!contains (db_l, "compat"))
{
// remove "files" and "nis", if there;
db_l = filter (string s, db_l, ``(
s != "files" && s != "nis"));
// put "compat" and the rest;
db_l = prepend (db_l, "compat");
Nsswitch::WriteDb (db, db_l);
}
// *_compat may be set to nisplus, nuke it (#16168)
string db_c = db + "_compat";
Nsswitch::WriteDb (db_c, []);
});
y2milestone("Writing pluses");
WritePluses ();
foreach (string db, nis_dbs, {
list<string> db_l = Nsswitch::ReadDb (db);
if (!contains (db_l, "nis"))
{
if (db == "netgroup")
db_l = ["nis"];
else
db_l = ["files", "nis"];
Nsswitch::WriteDb (db, db_l);
}
});
}
else // not start
{
y2milestone("not writing pluses");
boolean have_plus = HavePlus ();
if (!have_plus)
{
foreach (string db, dbs, ``{
list<string> db_l = Nsswitch::ReadDb (db);
// remove "nis" if there;
db_l = filter (string s, db_l, ``(s != "nis"));
// if nothing left, put "files";
// NOT. just remove it, meaning compat. #35299
Nsswitch::WriteDb (db, db_l);
});
}
foreach (string db, nis_dbs, {
list<string> db_l = Nsswitch::ReadDb (db);
db_l = filter (string s, db_l, ``(s != "nis"));
if (db_l == [])
db_l = ["files"];
Nsswitch::WriteDb (db, db_l);
});
}
if (!SCR::Write (.etc.nsswitch_conf, nil))
{
Report::Error (Message::ErrorWritingFile ("/etc/nsswitch.conf"));
return false;
}
return true;
}
/**
* Only write new configuration w/o starting any scripts
* @return true on success
*/
global define boolean WriteOnly()``{
if (start)
{
if (Package::Installed ("rpcbind"))
rpc_mapper = "rpcbind";
else
rpc_mapper = "portmap";
Service::Enable (rpc_mapper);
Service::Enable("ypbind");
if (!SCR::Write (.etc.defaultdomain, domain))
{
Report::Error (Message::ErrorWritingFile("/etc/defaultdomain"));
return false;
}
// so that dhcpcd cannot restore it
SCR::Execute (.target.remove, "/etc/yp.conf.sv");
setNetconfigValues();
SCR::Execute(.target.bash, "/sbin/netconfig update");
SCR::Write (.sysconfig.ypbind.YPBIND_LOCAL_ONLY, local_only? "yes":"no");
SCR::Write (.sysconfig.ypbind.YPBIND_BROADCAST, global_broadcast? "yes":"no");
SCR::Write (.sysconfig.ypbind.YPBIND_BROKEN_SERVER, broken_server? "yes":"no");
SCR::Write (.sysconfig.ypbind.YPBIND_OPTIONS, options);
if (! SCR::Write (.sysconfig.ypbind, nil))
{
Report::Error (Message::ErrorWritingFile (
"/etc/sysconfig/ypbind"));
return false;
}
SCR::Write (.sysconfig.network.config.NETCONFIG_NIS_SETDOMAINNAME,
policy == "" ? "no" : "yes");
if (! SCR::Write (.sysconfig.network.dhcp, nil))
{
Report::Error (Message::ErrorWritingFile (
"/etc/sysconfig/network/dhcp"));
return false;
}
Autologin::Write (false);
}
else
{
Service::Disable("ypbind");
}
// TODO do as much as possible if one thing fails
// especially WRT nis/autofs independence
WriteNssConf ();
if (_autofs_allowed)
{
if (! Nsswitch::WriteAutofs (start && _start_autofs,"nis"))
{
return false;
}
if (_start_autofs)
{
Service::Enable("autofs");
}
else
{
Service::Disable("autofs");
}
}
boolean progress_orig = Progress::set (false);
SuSEFirewall::WriteOnly ();
Progress::set (progress_orig);
return true;
}
/**
* Saves NIS configuration.
* @return true on success
*/
global define boolean Write () ``{
if (!WriteOnly ())
{
return false;
}
// dialog label
Progress::New (_("Writing NIS Configuration..."), " ", 2, [
// progress stage label
_("Stop services"),
// progress stage label
_("Start services"),
], [
// progress step label
_("Stopping services..."),
// progress step label
_("Starting services..."),
// final progress step label
_("Finished") ],
"" );
// help text
Wizard::RestoreHelp(_("Writing NIS client settings"));
Progress::NextStage ();
if (dhcp_restart)
{
// Restart the dhcp client, if it is running, to parse the changed
// options
Service::RunInitScript ("network", "restart-all-dhcp-clients");
}
Service::Stop("ypbind");
Progress::NextStage ();
if (start)
{
if (Service::Status (rpc_mapper) != 0 )
{
if (Service::Start (rpc_mapper) == false)
{
Message::CannotStartService (rpc_mapper);
return false;
}
}
sleep(1000); // workaround for bug #10428, ypbind restart
map out = (map) SCR::Execute (.target.bash_output, "/etc/init.d/ypbind start", $["TERM": "raw"]);
if (out["exit"]:1 == 0)
{
YpbindErrors = "";
}
else
{
YpbindErrors = out["stdout"]:"internal error";
// error popup message
Report::Error (_("Error while running ypclient."));
return false;
}
// only test for a server if domain not changed
if (! domain_changed)
{
if (SCR::Execute(.target.bash, "/usr/bin/ypwhich >/dev/null") != 0)
{
// error popup message
Report::Error (_("NIS server not found."));
return false;
}
}
if (Autologin::modified)
SCR::Execute (.target.bash, "/sbin/SuSEconfig --module kdm3");
}
// remove nscd cache
if (Package::Installed ("nscd") && modified)
{
SCR::Execute (.target.bash, "/usr/sbin/nscd -i passwd");
SCR::Execute (.target.bash, "/usr/sbin/nscd -i group");
}
if (_autofs_allowed && touched)
{
Service::Stop("autofs");
if (_start_autofs)
{
Service::Start("autofs");
}
}
SuSEFirewall::ActivateConfiguration ();
// final stage
Progress::NextStage ();
return true;
}
/**
* Return needed packages and packages to be removed
* during autoinstallation.
* @return map of lists.
*
**/
global define map AutoPackages() ``{
list install_pkgs = required_packages;
list remove_pkgs = [];
return ($["install": install_pkgs, "remove": remove_pkgs]);
}
}
ACC SHELL 2018