ACC SHELL
/**
* File: include/security/dialogs.ycp
* Package: Security configuration
* Summary: Dialogs definitions
* Authors: Michal Svec <msvec@suse.cz>
*
* $Id: dialogs.ycp 58880 2009-10-01 11:48:57Z jsuchome $
*/
{
textdomain "security";
import "Label";
import "Popup";
import "Security";
import "Wizard";
include "security/helps.ycp";
include "security/routines.ycp";
list tree_dialogs = [ "main", "overview", "password", "boot", "login", "users", "misc", `wizardTree ];
const list<string> configurable_options = [ "PERMISSION_SECURITY", "RUNLEVEL3_MANDATORY_SERVICES",
"RUNLEVEL5_MANDATORY_SERVICES", "RUNLEVEL3_EXTRA_SERVICES", "RUNLEVEL5_EXTRA_SERVICES" ];
const string UNKNOWN_STATUS = _("Unknown");
string SecurityStatus(string option, boolean plaintext)
{
string ret = "";
string value = Security::Settings[option]:"";
y2milestone("Option: %1, value: %2", option, value);
// handle the special cases at first
if (contains(configurable_options, option))
{
ret = _("Configure");
}
else if (value == "yes")
{
ret = _("Enabled");
}
else if (value == "no")
{
ret = _("Disabled");
}
else
{
return UNKNOWN_STATUS;
}
if (plaintext)
{
return ret;
}
ret = sformat("<A HREF=\"%1\">%2</A>", option, ret);
return ret;
}
map<string,string> label_mapping = $[
"ENABLE_SYSRQ" : _("Use magic SysRq keys"),
"PERMISSION_SECURITY" : _("Use secure file permissions"),
"DISPLAYMANAGER_REMOTE_ACCESS" : _("Remote access to the display manager"),
"CWD_IN_ROOT_PATH" : _("Use current directory in root's path"),
"CWD_IN_USER_PATH" : _("Use current directory in path of regular users"),
"SYSTOHC" : _("Write back system time to the hardware clock"),
"SYSLOG_ON_NO_ERROR" : _("Always generate syslog message for cron scripts"),
"DHCPD_RUN_CHROOTED" : _("Run the DHCP daemon in a chroot"),
"DHCPD_RUN_AS" : _("Run the DHCP daemon as dhcp user"),
"DISPLAYMANAGER_ROOT_LOGIN_REMOTE" : _("Disable remote root login in the display manager"),
"DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN" : _("Disable remote access to the X server"),
"SMTPD_LISTEN_REMOTE" : _("Remote access to the email delivery subsystem"),
"DISABLE_RESTART_ON_UPDATE" : _("Disable service restart on update"),
"DISABLE_STOP_ON_REMOVAL" : _("Disable service stop on removal"),
"IP_TCP_SYNCOOKIES" : _("Enable TCP syncookies"),
"IP_FORWARD" : _("Disable IPv4 forwarding"),
"IPV6_FORWARD" : _("Disable IPv6 forwarding"),
"RUNLEVEL3_MANDATORY_SERVICES" : _("Enable basic system services in runlevel 3\n (multiuser with network)"),
"RUNLEVEL5_MANDATORY_SERVICES" : _("Enable basic system services in runlevel 5\n (multiuser with network and graphical login)"),
"RUNLEVEL3_EXTRA_SERVICES" : _("Enable extra services in runlevel 3"),
"RUNLEVEL5_EXTRA_SERVICES" : _("Enable extra services in runlevel 5"),
];
any OverviewText(symbol type)
{
string ret = "";
list<term> ret_table = [];
if (type == `richtext)
{
// open a table
ret = sformat("<TABLE><TR> <TD><BIG><B>%1</B></BIG></TD>
<TD ALIGN=center><BIG><B> %2 </B></BIG></TD>
<TD ALIGN=center><BIG><B> %3 </B></BIG></TD>
<TD></TD>
</TR> <TR></TR>",
// table header
_("Security Setting"), _("Status"), _("Security Status"));
}
list<map> security_mapping = [
$[
"id" : "ENABLE_SYSRQ",
"is_secure" : (Security::Settings["ENABLE_SYSRQ"]:"" == "no")
],
$[
"id" : "PERMISSION_SECURITY",
"is_secure" : (Security::Settings["PERMISSION_SECURITY"]:"" == "secure"
|| Security::Settings["PERMISSION_SECURITY"]:"" == "paranoid")
],
$[
"id" : "DISPLAYMANAGER_REMOTE_ACCESS",
"is_secure" : (Security::Settings["DISPLAYMANAGER_REMOTE_ACCESS"]:"" == "no"),
],
$[
"id" : "CWD_IN_ROOT_PATH",
"is_secure" : (Security::Settings["CWD_IN_ROOT_PATH"]:"" == "no")
],
$[
"id" : "CWD_IN_USER_PATH",
"is_secure" : (Security::Settings["CWD_IN_USER_PATH"]:"" == "no")
],
$[
"id" : "SYSTOHC",
"is_secure" : (Security::Settings["SYSTOHC"]:"" == "yes"),
],
$[
"id" : "SYSLOG_ON_NO_ERROR",
"is_secure" : (Security::Settings["SYSLOG_ON_NO_ERROR"]:"" == "yes"),
],
$[
"id" : "DHCPD_RUN_CHROOTED",
"is_secure" : (Security::Settings["DHCPD_RUN_CHROOTED"]:"" == "yes"),
],
$[
"id" : "DHCPD_RUN_AS",
"is_secure" : (Security::Settings["DHCPD_RUN_AS"]:"" == "dhcp"),
],
$[
"id" : "DISPLAYMANAGER_ROOT_LOGIN_REMOTE",
"is_secure" : (Security::Settings["DISPLAYMANAGER_ROOT_LOGIN_REMOTE"]:"" == "no"),
],
$[
"id" : "DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN",
"is_secure" : (Security::Settings["DISPLAYMANAGER_XSERVER_TCP_PORT_6000_OPEN"]:"" == "no"),
],
$[
"id" : "SMTPD_LISTEN_REMOTE",
"is_secure" : (Security::Settings["SMTPD_LISTEN_REMOTE"]:"" == "no"),
],
$[
"id" : "DISABLE_RESTART_ON_UPDATE",
"is_secure" : (Security::Settings["DISABLE_RESTART_ON_UPDATE"]:"" == "no"),
],
$[
"id" : "DISABLE_STOP_ON_REMOVAL",
"is_secure" : (Security::Settings["DISABLE_STOP_ON_REMOVAL"]:"" == "no"),
],
$[
"id" : "IP_TCP_SYNCOOKIES",
"is_secure" : (Security::Settings["IP_TCP_SYNCOOKIES"]:"" == "yes"),
],
$[
"id" : "IP_FORWARD",
"is_secure" : (Security::Settings["IP_FORWARD"]:"" == "no"),
],
$[
"id" : "IPV6_FORWARD",
"is_secure" : (Security::Settings["IPV6_FORWARD"]:"" == "no"),
],
$[
"id" : "RUNLEVEL3_MANDATORY_SERVICES",
"is_secure" : (Security::Settings["RUNLEVEL3_MANDATORY_SERVICES"]:"" == "secure"),
],
$[
"id" : "RUNLEVEL5_MANDATORY_SERVICES",
"is_secure" : (Security::Settings["RUNLEVEL5_MANDATORY_SERVICES"]:"" == "secure"),
],
$[
"id" : "RUNLEVEL3_EXTRA_SERVICES",
"is_secure" : (Security::Settings["RUNLEVEL3_EXTRA_SERVICES"]:"" == "secure"),
],
$[
"id" : "RUNLEVEL5_EXTRA_SERVICES",
"is_secure" : (Security::Settings["RUNLEVEL5_EXTRA_SERVICES"]:"" == "secure"),
],
];
foreach(map setting, security_mapping,
{
string current_value = Security::Settings[setting["name"]:""]:"";
string id = setting["id"]:"";
if (type == `table)
{
ret_table = add(ret_table, `item(`id(id), label_mapping[id]:"", SecurityStatus(id, true),
setting["is_secure"]:false ? "✔" : "✘"));
}
else if (type == `richtext)
{
// add one line for each security setting
ret = ret + sformat("<TR><TD>%1 </TD><TD ALIGN=center>%2</TD><TD ALIGN=center> %3</TD><TD>%4</TD></TR>",
label_mapping[id]:"",
SecurityStatus(id, false),
setting["is_secure"]:false ?
"<SUP><FONT COLOR=green SIZE=20>✔</FONT></SUP>" : "<FONT COLOR=red SIZE=20><SUP>✘</SUP></FONT>",
haskey(help_mapping, id) ? sformat("<A HREF=\"help_%1\">%2</A> <BR>", id, _("Help")) : ""
);
}
}
);
if (type == `table)
{
y2milestone("Overview table: %1", ret_table);
return ret_table;
}
else if (type == `richtext)
{
// close the table
ret = ret + "</TABLE>";
y2milestone("Overview text: %1", ret);
return ret;
}
y2error("Unknown type: %1", type);
return nil;;
}
// mapping for "Enable" and "Disable" links
// current value -> new value
map link_value_mapping = $[
"yes" : "no",
"no" : "yes"
];
// mapping for "Configure" links
// config name -> dialog name
map link_config_mapping = $[
"PERMISSION_SECURITY" : "misc"
];
// mapping for "Configure" links
// config name -> yast client
map link_client_mapping = $[
"RUNLEVEL3_MANDATORY_SERVICES" : "runlevel",
"RUNLEVEL5_MANDATORY_SERVICES" : "runlevel",
"RUNLEVEL3_EXTRA_SERVICES" : "runlevel",
"RUNLEVEL5_EXTRA_SERVICES" : "runlevel",
];
map link_update_mapping = $[
"RUNLEVEL3_MANDATORY_SERVICES" : ``(Security::ReadServiceSettings()),
"RUNLEVEL5_MANDATORY_SERVICES" : ``(Security::ReadServiceSettings()),
"RUNLEVEL3_EXTRA_SERVICES" : ``(Security::ReadServiceSettings()),
"RUNLEVEL5_EXTRA_SERVICES" : ``(Security::ReadServiceSettings()),
];
void DisplayHelpPopup(string help_id)
{
string help = help_mapping[help_id]:"";
// add the warning if the option is unknown
if (SecurityStatus(help_id, true) == UNKNOWN_STATUS)
{
help = help + HELPS["unknown_status"]:"";
}
// add extra help to service related options
if (help_id == "RUNLEVEL3_MANDATORY_SERVICES" || help_id == "RUNLEVEL5_MANDATORY_SERVICES")
{
integer runlevel = (help_id == "RUNLEVEL3_MANDATORY_SERVICES") ? 3 : 5;
list<list<string> > missing = Security::MissingMandatoryServices(runlevel);
if (missing != nil && missing != [])
{
string srvs = "";
foreach(list<string> l, missing,
{
// this is a separator between service names
// e.g.: "postfix" + " or " + "sendmail"
string group = mergestring(l , _(" or "));
srvs = srvs + group + "<BR>";
}
);
// richtext message: %1 = runlevel ("3" or "5"), %2 = list of services
help = help + sformat(_("<P>These basic system services are not enabled in runlevel %1:<BR><B>%2</B></P>"), runlevel, srvs);
}
else
{
help = help + _("<P>All basic services are enabled.</P>");
}
}
else if (help_id == "RUNLEVEL3_EXTRA_SERVICES" || help_id == "RUNLEVEL5_EXTRA_SERVICES")
{
integer runlevel = (help_id == "RUNLEVEL3_EXTRA_SERVICES") ? 3 : 5;
list<string> extra = Security::ExtraServices(runlevel);
if (extra != nil && extra != [])
{
string srvs = mergestring(extra, "<BR>");
help = help + sformat(_("<P>These extra services are enabled in runlevel %1:<BR><B>%2</B></P>"), runlevel, srvs);
help = help + _("<P>Check the list of services and disable all unused services.</P>");
}
else
{
help = help + _("<P>Only basic system services are enabled.</P>");
}
}
if (help != nil && help != "")
{
Popup::LongText(label_mapping[help_id]:_("Description"), `RichText(help), 70, 15);
}
}
define any OverviewDialog()
{
/* Overview dialog caption */
string caption = _("Security Overview");
string help = HELPS["overview"]:"";
boolean no_richtext = !(UI::GetDisplayInfo()["RichTextSupportsTable"]:true);
// table header
term tabheader = `header(_("Security Setting"), _("Status"), `Center(_("Security Status")));
term contents = no_richtext ?
`Table(`id(`table), `opt(`immediate), tabheader, OverviewText(`table)) :
`RichText(`id(`rtext), OverviewText(`richtext));
if (no_richtext)
{
// add a button box below the table
contents = `VBox(
contents,
`VSpacing(1),
`HBox(
// push button label
`PushButton(`id(`change), _("Change &Status")),
`HSpacing(2),
// push button label
`PushButton(`id(`descr), _("&Description"))
),
`VSpacing(1)
);
}
Wizard::SetContentsButtons(caption, contents, help,
Label::BackButton(), Label::OKButton());
Wizard::HideBackButton();
Wizard::SetAbortButton( `abort, Label::CancelButton() );
// select the dialog in the tree navigation
Wizard::SelectTreeItem("overview");
any ret = nil;
while(true) {
ret = UI::UserInput();
/* abort? */
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back || ret == `next || contains(tree_dialogs, ret)) {
// the current item has been selected, do not change to the same dialog
if (ret == "overview")
{
// preselect the item if it has been unselected
if (Wizard::QueryTreeItem() != "overview")
{
Wizard::SelectTreeItem("overview");
}
continue;
}
break;
}
// user clicked a link in the richtext
else if ((is(ret, string) && haskey(Security::Settings, ret)) || ret == `change)
{
if (ret == `change)
{
// query the table in textmode
ret = (string)UI::QueryWidget(`id(`table), `CurrentItem);
}
y2milestone("Clicked %1 link", ret);
string current_value = Security::Settings[(string)ret]:"";
string new_value = link_value_mapping[current_value]:current_value;
// set the new value and refresh the overview
if (haskey(link_value_mapping, current_value) && new_value != current_value)
{
y2milestone("New value for %1: %2", ret, new_value);
Security::Settings[(string)ret] = new_value;
// the config has been changed
Security::SetModified();
if (no_richtext)
{
UI::ChangeWidget(`id(`table), `Items, OverviewText(`table));
UI::ChangeWidget(`id(`table), `CurrentItem, ret);
UI::SetFocus(`id(`table));
}
else
{
UI::ChangeWidget(`id(`rtext), `Value, OverviewText(`richtext));
}
}
else if (haskey(link_config_mapping, ret))
{
string new_dialog = link_config_mapping[ret]:"";
y2milestone("Switching to dialog %1", new_dialog);
return new_dialog;
}
else if (haskey(link_client_mapping, ret))
{
string client = link_client_mapping[ret]:"";
if (client != "")
{
y2milestone("Calling Yast client %1", client);
any client_ret = WFM::CallFunction(client, []);
y2milestone("Client returned %1", client_ret);
if (client_ret == `next || client_ret == `ok || client_ret == `finish)
{
// update the current value
if (haskey(link_update_mapping, ret))
{
eval(link_update_mapping[ret]:nil);
}
// update the overview
if (no_richtext)
{
UI::ChangeWidget(`id(`table), `Items, OverviewText(`table));
UI::ChangeWidget(`id(`table), `CurrentItem, ret);
UI::SetFocus(`id(`table));
}
else
{
UI::ChangeWidget(`id(`rtext), `Value, OverviewText(`richtext));
}
}
}
}
else
{
y2error("Unknown action for link %1", ret);
}
}
else if ((is(ret, string) && regexpmatch((string)ret, "^help_")) || ret == `descr)
{
string help_id = no_richtext ?
(string)UI::QueryWidget(`id(`table), `CurrentItem)
: regexpsub((string)ret, "^help_(.*)", "\\1");
y2milestone("Clicked help link: %1", help_id);
DisplayHelpPopup(help_id);
// switch the focus back to the table in text/GTK UI
if (no_richtext)
{
UI::SetFocus(`id(`table));
}
}
else if (ret == `table)
{
// disable "Change Status" button if the action is unknown
string current_item = (string)UI::QueryWidget(`id(`table), `CurrentItem);
string status = SecurityStatus(current_item, true /* plaintext */);
UI::ChangeWidget(`id(`change), `Enabled, status != UNKNOWN_STATUS);
}
else {
y2error("Unexpected return code: %1", ret);
continue;
}
}
return ret;
}
/**
* Boot dialog
* @return dialog result
*/
define any BootDialog() ``{
/* Boot dialog caption */
string caption = _("Boot Settings");
string help = HELPS["boot"]:"";
/* Boot dialog contents */
term contents = `HVCenter(`HVSquash(`HBox(
`HSpacing(5),
`VBox(
`VSpacing(2),
/* Frame label */
`Frame(_("Boot Permissions"),`HBox(
`HSpacing(3),
`VBox(
`VSpacing(1),
settings2widget("CONSOLE_SHUTDOWN"),
`VSpacing(1.0),
settings2widget("DISPLAYMANAGER_SHUTDOWN"),
`VSpacing(1)
),
`HSpacing(3)
)),
`VSpacing(2)
),
`HSpacing(5)
)));
Wizard::SetContentsButtons(caption, contents, help,
Label::BackButton(), Label::OKButton());
Wizard::HideBackButton();
Wizard::SetAbortButton( `abort, Label::CancelButton() );
// select the dialog in the tree navigation
Wizard::SelectTreeItem("boot");
any ret = nil;
while(true) {
ret = UI::UserInput();
/* abort? */
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back || ret == `next || contains(tree_dialogs, ret)) {
// the current item has been selected, do not change to the same dialog
if (ret == "boot")
{
// preselect the item if it has been unselected
if (Wizard::QueryTreeItem() != "boot")
{
Wizard::SelectTreeItem("boot");
}
continue;
}
break;
}
else {
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next || contains(tree_dialogs, ret)) {
widget2settings("CONSOLE_SHUTDOWN");
widget2settings("DISPLAYMANAGER_SHUTDOWN");
}
return ret;
}
/**
* Misc dialog
* @return dialog result
*/
define any MiscDialog() ``{
/* Misc dialog caption */
string caption = _("Miscellaneous Settings");
string help = HELPS["misc"]:"";
/* Misc dialog contents */
term contents = `VBox(
VSeparator(),
settings2widget("PERMISSION_SECURITY"),
`VSpacing(1.0),
settings2widget("RUN_UPDATEDB_AS"),
`VSpacing(1.0),
settings2widget("CWD_IN_ROOT_PATH"),
VSeparator(),
settings2widget("CWD_IN_USER_PATH"),
`VSpacing(1.0),
settings2widget("ENABLE_SYSRQ"),
`VSpacing(1.8)
);
contents = `HVCenter(`HVSquash(`HBox(`HSpacing(5),`VBox(`VSpacing(2),`ReplacePoint(`id(`rp_main),contents),`VSpacing(2)),`HSpacing(5))));
Wizard::SetContentsButtons(caption, contents, help,
Label::BackButton(), Label::OKButton());
Wizard::HideBackButton();
Wizard::SetAbortButton( `abort, Label::CancelButton() );
// select the dialog in the tree navigation
Wizard::SelectTreeItem("misc");
any ret = nil;
while(true) {
ret = UI::UserInput();
/* abort? */
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back) {
break;
}
else if(ret == `next || contains(tree_dialogs, ret)) {
// the current item has been selected, do not change to the same dialog
if (ret == "misc")
{
// preselect the item if it has been unselected
if (Wizard::QueryTreeItem() != "misc")
{
Wizard::SelectTreeItem("misc");
}
continue;
}
/* check_* */
break;
}
else {
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next || contains(tree_dialogs, ret)) {
widget2settings("PERMISSION_SECURITY");
widget2settings("CWD_IN_ROOT_PATH");
widget2settings("CWD_IN_USER_PATH");
widget2settings("RUN_UPDATEDB_AS");
widget2settings("ENABLE_SYSRQ");
}
return ret;
}
/**
* Password dialog
* @return dialog result
*/
define any PassDialog() ``{
/* Password dialog caption */
string caption = _("Password Settings");
string help = HELPS["password"]:"";
/* Password dialog contents */
term contents = `VBox(
/* Frame label */
XFrame(0.3,0.15,_("Checks"),`VBox(
settings2widget("PASSWD_USE_CRACKLIB"),
VSeparator(),
settings2widget("PASS_MIN_LEN"),
VSeparator(),
settings2widget("PASSWD_REMEMBER_HISTORY"),
VSeparator ()
)),
`VSpacing(0.4),
settings2widget("PASSWD_ENCRYPTION"),
`VSpacing(0.4),
/* Frame label */
`Frame(_("Password Age"),`HBox(
`HSpacing(0.4),
settings2widget("PASS_MIN_DAYS"),
`HSpacing(0.4),
settings2widget("PASS_MAX_DAYS"),
`HSpacing(0.4)
)),
`VSpacing(0.15),
settings2widget("PASS_WARN_AGE"),
`VSpacing(0.0)
);
contents = `HVCenter(`HVSquash(`HBox(`HSpacing(5),`VBox(`VSpacing(2),`ReplacePoint(`id(`rp_main),contents),`VSpacing(2)),`HSpacing(5))));
Wizard::SetContentsButtons(caption, contents, help,
Label::BackButton(), Label::OKButton());
Wizard::HideBackButton();
Wizard::SetAbortButton( `abort, Label::CancelButton() );
// select the dialog in the tree navigation
Wizard::SelectTreeItem("password");
UI::ChangeWidget (`id ("PASS_MIN_LEN"), `Enabled,
Security::Settings["PASSWD_USE_CRACKLIB"]:"" == "yes");
any ret = nil;
while(true) {
ret = UI::UserInput();
/* abort? */
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back) {
break;
}
else if (ret == "PASSWD_USE_CRACKLIB")
{
// minlen is an option for pam_cracklib
UI::ChangeWidget (`id ("PASS_MIN_LEN"), `Enabled,
UI::QueryWidget (`id (ret), `Value) == true);
}
else if(ret == `next || contains(tree_dialogs, ret)) {
// the current item has been selected, do not change to the same dialog
if (ret == "password")
{
// preselect the item if it has been unselected
if (Wizard::QueryTreeItem() != "password")
{
Wizard::SelectTreeItem("password");
}
continue;
}
/* check_* */
if(checkMinMax("PASS_MIN_DAYS","PASS_MAX_DAYS") != true) {
/* Popup text */
Popup::Error(_("The minimum number of days cannot be larger
than the maximum."));
continue;
}
string enc =
(string) UI::QueryWidget(`id("PASSWD_ENCRYPTION"), `Value);
integer min = (integer) UI::QueryWidget(`id("PASS_MIN_LEN"),`Value);
if (min > Security::PasswordMaxLengths[enc]:8)
{
// Popup text, %1 is number
Popup::Error (sformat (_("The minimum password length cannot be larger than the maximum.
The maximum password length for the selected encryption method is %1."),
Security::PasswordMaxLengths[enc]:8));
continue;
}
break;
}
else if (ret != "PASSWD_ENCRYPTION") {
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next || contains(tree_dialogs, ret)) {
widget2settings("PASS_MIN_DAYS");
widget2settings("PASS_MAX_DAYS");
widget2settings("PASS_MIN_LEN");
widget2settings("PASSWD_USE_CRACKLIB");
widget2settings("PASS_WARN_AGE");
widget2settings("PASSWD_ENCRYPTION");
widget2settings("PASSWD_REMEMBER_HISTORY");
}
return ret;
}
/**
* Login dialog
* @return dialog result
*/
define any LoginDialog() ``{
/* Login dialog caption */
string caption = _("Login Settings");
string help = HELPS["login"]:"";
/* Login dialog contents */
term contents = `VBox(
/* Frame label */
XFrame(3.0,1.0,_("Login"),`VBox(
//VSeparator(),
settings2widget("FAIL_DELAY"),
//VSeparator(),
`VSpacing(0.5),
settings2widget("LASTLOG_ENAB"),
VSeparator(),
settings2widget("DISPLAYMANAGER_REMOTE_ACCESS")
//VSeparator()
))
//,`VSpacing(1.7)
);
contents = `HVCenter(`HVSquash(`HBox(`HSpacing(5),`VBox(`VSpacing(2),`ReplacePoint(`id(`rp_main),contents),`VSpacing(2)),`HSpacing(5))));
Wizard::SetContentsButtons(caption, contents, help,
Label::BackButton(), Label::OKButton());
Wizard::HideBackButton();
Wizard::SetAbortButton( `abort, Label::CancelButton() );
// select the dialog in the tree navigation
Wizard::SelectTreeItem("login");
any ret = nil;
while(true) {
ret = UI::UserInput();
/* abort? */
if(ret == `abort || ret == `cancel) {
if(ReallyAbort()) break;
else continue;
}
else if(ret == `back) {
break;
}
else if(ret == `next || contains(tree_dialogs, ret)) {
// the current item has been selected, do not change to the same dialog
if (ret == "login")
{
// preselect the item if it has been unselected
if (Wizard::QueryTreeItem() != "login")
{
Wizard::SelectTreeItem("login");
}
continue;
}
/* check_* */
break;
}
else {
y2error("Unexpected return code: %1", ret);
continue;
}
}
if(ret == `next || contains(tree_dialogs, ret)) {
widget2settings("LASTLOG_ENAB");
widget2settings("FAIL_DELAY");
widget2settings("DISPLAYMANAGER_REMOTE_ACCESS");
}
return ret;
}
/* EOF */
}
ACC SHELL 2018