ACC SHELL

Path : /usr/share/YaST2/include/samba-client/
File Upload :
Current File : //usr/share/YaST2/include/samba-client/dialogs.ycp

/* File:	include/samba-client/dialogs.ycp
 * Package:	Configuration of samba-client
 * Summary:	Dialogs definitions
 * Authors:	Stanislav Visnovsky <visnov@suse.cz>
 *
 * $Id: dialogs.ycp 61563 2010-04-01 11:20:25Z jsuchome $
 */

{

textdomain "samba-client";

import "Autologin";
import "CWMFirewallInterfaces";
import "Directory";
import "Label";
import "Message";
import "Mode";
import "Package";
import "Popup";
import "Samba";
import "SambaConfig";
import "Stage";
import "Wizard";

include "samba-client/helps.ycp";
include "samba-client/routines.ycp";

/**
 * Popup for editing the mount entry data
 */
map MountEntryPopup (map volume) {

    // labels of keys which are shown only if they are already present in the
    // volume entry (manualy added to congig file)
    map<string,string> key2label	= $[
	// text entry label
	"uid"		: _("U&ID"),
	// text entry label
	"pgrp"		: _("&Primary Group Name"),
	// text entry label
	"sgrp"		: _("&Secondary Group Name"),
	// text entry label
	"gid"		: _("&GID"),

	// we do not show "fstype" key, this is limited to cifs...
    ];

    term input_fields	= `VBox (
	// text entry label
	`InputField (`id ("server"), `opt (`hstretch), _("&Server Name")),
	// text entry label
	`InputField (`id ("path"), `opt (`hstretch), _("Remote &Path")),
	// text entry label
	`InputField (`id ("mountpoint"), `opt (`hstretch), _("&Mount Point")),
	// text entry label
	`InputField (`id ("options"), `opt (`hstretch), _("O&ptions")),
	// text entry label
	`InputField (`id ("user"), `opt (`hstretch), _("&User Name"))
    );
    // default keys
    list<string> widgets = [ "server", "path", "mountpoint", "options", "user"];

    foreach (string key, string label, key2label, {
	if (haskey (volume, key))
	{
	    input_fields	= add (input_fields,
		`InputField (`id (key), `opt (`hstretch), label));
	    widgets		= add (widgets, key);
	}
    });

    UI::OpenDialog (`opt (`decorated), `HBox (`HSpacing (0.2), `VBox (
	`VSpacing (0.2),
	input_fields,
	`VSpacing (0.2),
	`HBox (
	    `PushButton (`id (`ok), Label::OKButton ()),
	    `PushButton (`id (`cancel), Label::CancelButton ())
	),
	`VSpacing (0.2)
    ), `HSpacing (0.2)));

    if (volume == $[])
    {
	// offer this as a default option for new volumes (bnc#433845)
	volume["options"]	= "user=%(DOMAIN_USER)";
    }
    foreach (string key, widgets, {
	UI::ChangeWidget (`id (key), `Value, volume[key]:"");
    });

    any ret	= UI::UserInput ();
    if (ret == `ok)
    {
	// saving value to the same map we got as argument =>
	// keys that were not shown (e.g. fstype) are preserved)
	foreach (string key, widgets, {
	    volume[key]	= UI::QueryWidget (`id (key), `Value);
	});
    }
    UI::CloseDialog ();

    // filter out default keys without value (but leave the rest, so they
    // may appear on next editing)
    volume	= filter (string k, string v, (map<string,string>)volume, ``(
	v != "" ||
	!contains (["server", "path", "mountpoint", "options", "user"], k)
    ));
    // nothing was added, remove the proposal
    if (size (volume) == 1 && volume["options"]:"" == "user=%(DOMAIN_USER)")
	volume	= $[];
    return volume;
}

/**
 * dialog for setting expert settings, like winbind uid/gid keys (F301518)
 */
symbol ExpertSettingsDialog (boolean use_winbind) {

    string winbind_uid	= SambaConfig::GlobalGetStr ("winbind uid","10000-20000");
    list l		= splitstring (winbind_uid, "-");
    integer uid_min	= tointeger (l[0]:"10000");
    if (uid_min == nil) uid_min = 10000;
    integer uid_max	= tointeger (l[1]:"20000");
    if (uid_max == nil) uid_max = 20000;

    string winbind_gid	= SambaConfig::GlobalGetStr ("winbind gid","10000-20000");
    l			= splitstring (winbind_gid, "-");
    integer gid_min	= tointeger (l[0]:"10000");
    if (gid_min == nil) gid_min = 10000;
    integer gid_max	= tointeger (l[1]:"20000");
    if (gid_max == nil) gid_max = 20000;
    boolean dhcp_support	= Samba::GetDHCP ();

    // help text, do not translate 'winbind uid', 'winbind gid'
    string help_text	= _("<p>Specify the <b>Range</b> for Samba user and group IDs (<tt>winbind uid</tt> and <tt>winbind gid</tt> values).</p>")

    + HostsResolutionHelp ()
    + DHCPSupportHelp ()
    + PAMMountHelp ();

    boolean hosts_resolution	= Samba::GetHostsResolution ();

    list<term> mount_items	= [];
    list<map> non_cifs_volumes	= [];

    // mapping of unique ID's to volume entries
    map<integer,map> mount_map	= $[];
    integer i			= 0;

    foreach (map volume, Samba::GetPAMMountVolumes (), {
	if (volume["fstype"]:"" != "cifs")
	{
	    y2debug ("volume fstype different from cifs, skipping");
	    non_cifs_volumes	= add (non_cifs_volumes, volume);
	    return;
	}
	mount_map[i]	= volume;
	i		= i + 1;
    });

    list<term> build_mount_items () {

	mount_items	= maplist (integer id, map volume, mount_map, {
	    return `item (`id (id),
		volume["server"]:"", volume["path"]:"",
		volume["mountpoint"]:"", volume["user"]:"",
		volume["options"]:"");
	});
	return mount_items;
    }

    term contents	= `HBox (`HSpacing (3), `VBox (
	`VSpacing (0.4),
	// frame label
	`Frame (_("&UID Range"), `HBox (
		// int field label
		`IntField (`id (`uid_min), _("&Minimum"), 0, 99999, uid_min),
		// int field label
		`IntField (`id (`uid_max), _("Ma&ximum"), 0, 99999, uid_max)
	)),
	`VSpacing (0.5),
	// frame label
	`Frame (_("&GID Range"), `HBox (
		// int field label
		`IntField (`id (`gid_min), _("M&inimum"), 0, 99999, gid_min),
		// int field label
		`IntField (`id (`gid_max), _("M&aximum"), 0, 99999, gid_max)
	)),
	`VSpacing (),
	// frame label
	`Frame (_("Windows Internet Name Service"), `VBox (
	    HostsResolutionTerm (hosts_resolution),
	    DHCPSupportTerm (dhcp_support)
	)),
	`VSpacing (0.4),
	// frame label
	`Frame (_("Mount Server Directories"), `VBox (
	    `Table (`id (`table), `opt(`notify), `header (
		// table header
		_("Server Name"),
		// table header
		_("Remote Path"),
		// table header
		_("Local Mount Point"),
		// table header
		_("User Name"),
		// table header
		_("Options")),
		build_mount_items ()
	    ),
	    `HBox (
		`PushButton (`id (`add), Label::AddButton ()),
		`PushButton (`id (`edit), Label::EditButton ()),
		`PushButton (`id (`delete), Label::DeleteButton ()),
		`HStretch ()
	    )
	))
    ), `HSpacing (3));

    Wizard::OpenOKDialog ();
    // dialog title
    Wizard::SetContents (_("Expert Settings"), contents, help_text, true, true);

    foreach (symbol s, [`edit, `delete], {
	UI::ChangeWidget (`id (s), `Enabled, size (mount_items) > 0);
    });

    any ret		= `cancel;
    integer selected	= 0;
    while (true)
    {
	any ret	= UI::UserInput ();
	if (ret == `cancel)
	    break;
	if (ret == `delete || ret == `edit || ret == `table)
	{
	    selected	= (integer) UI::QueryWidget (`id (`table),`CurrentItem);
	    if (ret == `table)
		ret	= `edit;
	}
	if (ret == `delete)
	{
	    mount_map	= remove (mount_map, selected);
	    UI::ChangeWidget (`id (`table), `Items, build_mount_items ());
	    foreach (symbol s, [`edit, `delete], {
		UI::ChangeWidget (`id (s), `Enabled, size (mount_items) > 0);
	    });
	}
	if (ret == `add || ret == `edit)
	{
	    map volume	= ret == `edit ? mount_map[selected]:$[] : $[];
	    volume	= MountEntryPopup (volume);
	    if (volume == $[])
		continue;
	    if (ret == `add)
		volume["fstype"]	= "cifs";
	    integer id		= ret == `edit ? selected : size (mount_map);
	    mount_map[id]	= volume;
	    UI::ChangeWidget (`id (`table), `Items, build_mount_items ());
	    foreach (symbol s, [ `edit, `delete], {
		UI::ChangeWidget (`id (s), `Enabled, size (mount_items) > 0);
	    });
	}
	if (ret == `ok)
	{
	    uid_min	= (integer) UI::QueryWidget (`id (`uid_min),`Value);
	    uid_max	= (integer) UI::QueryWidget (`id (`uid_max),`Value);
	    gid_min	= (integer) UI::QueryWidget (`id (`gid_min),`Value);
	    gid_max	= (integer) UI::QueryWidget (`id (`gid_max),`Value);
	    if (uid_min >= uid_max || gid_min >= gid_max)
	    {
		// error popup: min >= max
		Popup::Error (_("The minimum value in the range cannot be
larger than maximum one.\n"));
		continue;
	    }
	    string winbind_uid_new = sformat ("%1-%2", uid_min, uid_max);
	    string winbind_gid_new = sformat ("%1-%2", gid_min, gid_max);
	    if (winbind_uid_new != winbind_uid)
		SambaConfig::GlobalSetStr ("winbind uid", winbind_uid_new);
	    if (winbind_gid_new != winbind_gid)
		SambaConfig::GlobalSetStr ("winbind gid", winbind_gid_new);
	    Samba::SetDHCP ((boolean)UI::QueryWidget (`id (`dhcp), `Value));
	    Samba::SetHostsResolution (
		(boolean)UI::QueryWidget (`id (`hosts_resolution), `Value));

	    list<map> updated_volumes	= non_cifs_volumes;
	    foreach (integer id, map volume, mount_map, {
		updated_volumes	= add (updated_volumes, volume);
	    });
	    Samba::SetPAMMountVolumes (updated_volumes);
	    break;
	}
    }
    UI::CloseDialog ();
    return (symbol) ret;
}

/**
 * Samba memberhip dialog
 * @return dialog result
 */
symbol MembershipDialog () {
    /* Samba-client workgroup dialog caption */
    string caption = _("Windows Domain Membership");
    boolean mkhomedir	= Samba::mkhomedir;
    boolean allow_share	= true;
    integer max_shares	= Samba::GetMaxShares ();
    if (max_shares == 0)
    {
	max_shares	= 100;
	allow_share	= false;
    }
    string shares_group	= Samba::shares_group;
    boolean guest	= allow_share && Samba::GetGuessAccess ();
    term status_term	= `VBox(
	`ReplacePoint (`id(`rpstatus), `Empty())
    );
    map pw_data	= Samba::password_data;
    string left_domain	= "";

    // internal function: update the status line
    void check_domain_membership (string domain) {

	Samba::SetWorkgroup(domain);

	if (Mode::config ())
	    return;

	// busy popup text
	Popup::ShowFeedback ("",_("Verifying AD domain membership..."));
	SambaAD::ReadADS (domain);
	if (SambaAD::ADS () != "")
	{
	    domain = SambaAD::GetWorkgroup (domain);
	    Samba::SetWorkgroup(domain);
	    SambaAD::ReadRealm ();
	}
	Popup::ClearFeedback ();

	term leave_button	= (SambaAD::ADS () == "") ? `Empty () :
	    // push button label
	    `PushButton (`id (`leave), _("&Leave"));
	UI::ReplaceWidget (`id(`rpstatus),
	    (Stage::cont () || CheckWorkgroup (domain) != `joined_domain) ?
	    `Empty() :
	    `HBox (
		// status label
		`Left (`Label (_("Currently a member of this domain"))),
		`HStretch (),
		leave_button
	    )
	);
    }

    // winbind enabled on start
    boolean was_winbind	= Samba::GetWinbind();

    term winbind_term	= Stage::cont() ? `Empty () : `VBox (
	`VSpacing (0.4),
	`Left(`CheckBox(`id(`winbind), `opt (`notify),
	    // translators: checkbox label to enable winbind
	    _("Also &Use SMB Information for Linux Authentication"),
	    Samba::GetWinbind()
	))
    );

    term mkhomedir_term	= `VBox (
	`Left(`CheckBox(`id(`mkhomedir),
	    // checkbox label
	    _("&Create Home Directory on Login"), mkhomedir
	))
    );

    term autoyast_term	= Mode::config () ? `VBox (
	`VSpacing (),
	// frame label
	`Frame (_("Join Settings"), `HBox (
	    // text entry label
	    `InputField (`id("user"), `opt (`hstretch), _("&Username"),
		pw_data["user"]:"" != nil ? pw_data["user"]:"" : ""),
	    // text entry label
	    `Password (`id("password"), `opt (`hstretch), _("&Password"),
		pw_data["password"]:""),
	    // text entry label
	    `InputField (`id("machine"), `opt (`hstretch), _("Mac&hine Account OU"),
		pw_data["machine"]:"" != nil ? pw_data["machine"]:"" : "")
	)),
	`VSpacing (),
	// text entry label
	`InputField (`id(`ads), `opt (`hstretch), _("Active Directory Server"))
    ) : `Empty ();

    term ntp_term	= Mode::config () ? `Empty () : `VBox (
	`VSpacing (0.4),
	// button label (run YaST client for NTP)
	`Right (`PushButton (`id(`ntp), _("N&TP Configuration...")))
    );

    // checkbox label
    string text_nscd	= _("Disable Name Service Cache");
    // checkbox label
    string text_fam	= _("Start File Alteration Monitor");

    map<string,any> firewall_widget =
	CWMFirewallInterfaces::CreateOpenFirewallWidget ($[
	    "services"	: [ "samba-server" ],
	    "display_details" : true,
	]);
    term firewall_layout = firewall_widget["custom_widget"]:`VBox ();

//    Wizard::SetContentsButtons( caption, `HVSquash( `VBox(
    Wizard::SetContentsButtons (caption, `HBox (`HSpacing (3), `VBox (
	// translators: frame label
	`Frame (_("Membership"),
	    `VBox (
		`HBox(
		    `HSpacing (0.2),
		    `InputField (`id(`workgroup), `opt (`hstretch),
			(Stage::cont() ?
			_("&Domain") :
			// translators: text entry label
			_("&Domain or Workgroup")), Samba::GetWorkgroupOrRealm()
		    )
		),
		status_term,
		winbind_term,
		`HBox (
		    Stage::cont () ? `Empty () : `HSpacing (2),
		    `VBox (
			mkhomedir_term,
			`Left (
			    // checkbox label
			   `CheckBox(`id(`caching),_("Off&line Authentication"),
			    Samba::GetWinbindCaching ())
			),
			`Left (
			    // checkbox label
			   `CheckBox (`id(`ssh),_("&Single Sign-On for SSH"),
				Samba::GetSSHSupport ())
			),
			`VSpacing (0.2)
		    )
		)
	    )
	),
	`VSpacing (0.4),
	// button label
	`Right (`PushButton (`id(`expert), _("&Expert Settings..."))),
	SharesTerm ($[
	    "allow_share"	: allow_share,
	    "group"		: shares_group,
	    "max_shares"	: max_shares,
	    "guest_access"	: guest
	]),
	autoyast_term,
	ntp_term
    ), `HSpacing (3)),
	(Stage::cont() ? HELPS["MembershipDialog_cont"]:"" :
	    HELPS["MembershipDialog_nocont"]:"") +
	HELPS["MembershipDialog_common"]:"" +
	SharesHelp () +
	(Mode::config () ? HELPS["MembershipDialog_config"]:"" :
	    HELPS["MembershipDialog_NTP"]:""),
	Stage::cont() ? Label::BackButton() : Label::CancelButton(),
	Stage::cont() ? Label::NextButton() : Label::OKButton()
    );
//    CWMFirewallInterfaces::OpenFirewallInit (firewall_widget, "");
    foreach (symbol t, [`mkhomedir, `caching, `ssh], {
	UI::ChangeWidget (`id(t), `Enabled, Samba::GetWinbind() || Stage::cont());
    });
    foreach (symbol t, [`group, `max_shares, `guest_ch], {
	UI::ChangeWidget (`id(t), `Enabled, allow_share);
    });

    if (!Stage::cont()) {
	Wizard::HideAbortButton();
	check_domain_membership (Samba::GetWorkgroupOrRealm());
    }

    any ret = nil;
    while(true) {

	map event	= UI::WaitForEvent ();
	ret		= (symbol) event["ID"]:nil;
//	CWMFirewallInterfaces::OpenFirewallHandle(firewall_widget,"",event);
	boolean use_winbind = Stage::cont() ? true :
	    (boolean)UI::QueryWidget(`id(`winbind), `Value);

	if (ret == `abort || ret == `cancel || (ret == `back && !Stage::cont()))
	{
	    if(ReallyAbort()) break;
	    else continue;
	}
	else if (ret == `leave)
	{
	    string workgroup = (string)UI::QueryWidget(`id(`workgroup), `Value);
	    if (LeaveDomain (workgroup) == `ok)
	    {
		left_domain	= workgroup;
		check_domain_membership (workgroup);
		UI::ChangeWidget(`id(`winbind), `Value, false);
		SambaAD::SetADS ("");
	    }
	}
	else if (ret == `winbind) {
	    UI::ChangeWidget (`id(`mkhomedir), `Enabled, use_winbind);
	    UI::ChangeWidget (`id(`caching), `Enabled, use_winbind);
	    UI::ChangeWidget (`id(`ssh), `Enabled, use_winbind);
	}
	else if (ret == `share_ch) {
	    foreach (symbol t, [`group, `max_shares, `guest_ch], {
		UI::ChangeWidget (`id(t), `Enabled,
		    (boolean) UI::QueryWidget(`id(`share_ch),`Value)
		);
	    });
	}
	else if (ret == `expert)
	{
	    ExpertSettingsDialog (use_winbind);
	}
	else if (ret == `ntp)
	{
	    if (Package::InstallAll ( ["yast2-ntp-client"]))
	    {
		string workgroup = (string)UI::QueryWidget(`id(`workgroup), `Value);
		string ads = SambaAD::ReadADS(workgroup);
		string tmpfile = Directory::vardir + "/ad_ntp_data.ycp";
		map <string, string> ad_data = $[
		    "ads" : ads,
		];
		SCR::Write(.target.ycp, tmpfile, ad_data);
		WFM::CallFunction ("ntp-client", []);
	    }
	}
        else if(ret == `next) {
	    string workgroup = (string)UI::QueryWidget(`id(`workgroup), `Value);
	    if (workgroup != Samba::GetWorkgroup () &&
		(left_domain == "" || workgroup != left_domain))
	    {
		check_domain_membership (workgroup);
		workgroup       = Samba::GetWorkgroup ();
	    }

	    Samba::SetWinbind (use_winbind);

	    if (use_winbind)
	    {
		list<string> packages	= ["samba-winbind"];
		if (SambaAD::ADS () != "")
		{
		    packages = (list<string>)merge(packages,["krb5","krb5-client"]);
		}
		if (Samba::PAMMountModified () && size (Samba::GetPAMMountVolumes ()) > 0)
		{
		    packages	= add (packages, "pam_mount");
		}
		if (!Package::InstallAll (packages))
		{
		    Popup::Error (Message::FailedToInstallPackages ());
		    ret = `not_next;
		    UI::ChangeWidget(`id(`winbind), `Value, false);
		    continue;
		}
	    }

	    // for domain ask to join
	    symbol workgroup_type = CheckWorkgroup(workgroup);

	    if (Mode::config())
	    {
		foreach (string key, [ "user", "password", "machine" ], {
		    string val = (string) UI::QueryWidget(`id(key),`Value);
		    if (val != nil && val != "")
			Samba::password_data[key]	= val;
		});
		if ((string)UI::QueryWidget(`id(`ads),`Value) != "")
		    SambaAD::SetADS ((string)UI::QueryWidget(`id(`ads),`Value));
	    }
	    else
	    {

		if (Samba::GetWinbind() && workgroup_type == `workgroup)
		{
		    Popup::Error(
		    // 1st part of an error message:
		    // winbind cannot provide user information taken from
		    // a workgroup, must be a domain; %1 is the workgroup name
		    sformat( _("Cannot use the workgroup\n'%1' for Linux authentication."), workgroup)
		    + "\n\n"
		    + (Stage::cont()
			// translators: 2nd part of an error message
			? _("Enter a valid domain.")
			// translators: 2nd part of an error message
			: _("Enter a domain or disable\nusing SMB for Linux authentication.")));
		    continue;
		}

		symbol in_domain = nil;
		if (Stage::cont() && workgroup_type != `joined_domain)
		{
		    // return `ok or `fail
		    in_domain = JoinDomain(workgroup);
		    Samba::in_domain    = in_domain;
		    if (in_domain == `fail) continue;
		}

		if (false) // we might use it to warn user (#155716)
		{
		    // continue/cancel popup
		    Popup::ContinueCancel (sformat (_("Configuring this system as a client for Active Directory resets the following
settings in smb.conf to the default values:
%1"), mergestring (["domain master", "domain logons"], "\n")));
		}
		if (!Stage::cont() &&
		   (left_domain=="" || use_winbind || left_domain != workgroup))
		{
		    // return `ok, `fail or `nojoin
		    in_domain = AskJoinDomain(workgroup, workgroup_type);
		    if (in_domain == `fail) continue;
		    if (in_domain != `ok && Samba::GetWinbind()) {
			// 1st part of an error message:
			// winbind cannot provide user information if the host
			// is not in a domain
			Popup::Error( _("The host must be a member of a domain\nfor Linux authentication using SMB.")
			    + "\n\n"
			    // translators: 2nd part of an error message
			    + _("Join a domain or disable use of SMB\nfor Linux authentication."));
			continue;
		    }
		}
		if (Samba::GetWinbind()) {
		    // used outside this module for autologin function. must be complete sentence.
		    Autologin::AskForDisabling(_("Samba is now enabled."));
		}
	    }
	    if (Mode::config () ||
		(Stage::cont() && Samba::in_domain == `ok &&
		Samba::network_setup["dhcp","DHCLIENT_SET_HOSTNAME"]:"yes" == "yes"))
	    {
		// yes/no popup text
		Samba::disable_dhcp_hostname	= Popup::YesNo (_("In a Microsoft environment,
hostname changes with DHCP are problematic.
Disable hostname changes with DHCP?"));
	    }


	    Samba::SetMkHomeDir (use_winbind &&
		(boolean)UI::QueryWidget(`id(`mkhomedir), `Value));
	    Samba::SetWinbindCaching (use_winbind &&
		(boolean)UI::QueryWidget(`id(`caching), `Value));
	    Samba::SetSSHSupport (use_winbind &&
		(boolean)UI::QueryWidget (`id(`ssh), `Value));

	    boolean new_share = (boolean)UI::QueryWidget(`id(`share_ch),`Value);
	    if (new_share && ! allow_share && SharesExist (Samba::shares_dir))
	    {
		Samba::remove_shares = AskForSharesRemoval ();
	    }
	    integer max = (integer)UI::QueryWidget(`id(`max_shares),`Value);
	    if (!new_share)
	    {
		max = 0;
		if (allow_share)
		    Samba::stop_services	= AskToStopServices ();
	    }
	    Samba::SetShares (max,(string)UI::QueryWidget(`id(`group),`Value));
	    Samba::SetGuessAccess (new_share &&
		(boolean)UI::QueryWidget(`id(`guest_ch), `Value));
	    if(!Stage::cont() && !Mode::config() && use_winbind&& !was_winbind){
		// message popup, part 1/2
		Popup::Message (
_("This change only affects newly created processes and not already
running services. Restart your services manually or reboot 
the machine to enable it for all services.
"));
	    }
//	    CWMFirewallInterfaces::OpenFirewallStore (firewall_widget,"",event);
	    break;
	} else if (ret == `back ) {
	    break;
	}
    }

    Wizard::RestoreNextButton();
    Wizard::RestoreBackButton();
    return (symbol) ret;
}

/* EOF */
}

ACC SHELL 2018