ACC SHELL
/**
* File: include/samba-client/routines.ycp
* Package: Configuration of samba-client
* Summary: Miscelanous functions for configuration of samba-client.
* Authors: Stanislav Visnovsky <visnov@suse.cz>
*
* $Id: routines.ycp 60041 2009-12-10 12:59:56Z jsuchome $
*/
{
textdomain "samba-client";
import "FileUtils";
import "Mode";
import "Label";
import "Stage";
import "Popup";
import "Service";
import "String";
import "Samba";
import "SambaConfig";
import "SambaNetJoin";
import "SambaNmbLookup";
import "SambaAD";
/**
* Allow user to type in a user/password pair in a popup.
*
* @param message a text to be displayed above the password text entry
* @param defaultuser a pre-filled user name
* @return map<string, string> $["user": string, "password": string] with information
* provided by the user or nil on cancel
*/
map<string, string> passwordUserPopup (string message, string defaultuser, string domain, symbol what)
{
term machine_term = `Empty ();
string default_id = "default_entry";
// default value of Machine Account
term default_entry= `item (`id (default_id), _("(default)"));
if (SambaAD::ADS () != "" && what != `leave)
{
list machines = [ default_entry ];
machine_term = `HBox (
`ReplacePoint (`id (`rpcombo),
`Left (`ComboBox (`id (`machines), `opt (`hstretch),
// combo box label
_("&Machine Account OU"), machines)
)
),
`VBox (
`Label (""),
`PushButton (`id (`acquire), _("O&btain list"))
)
);
}
UI::OpenDialog (`opt (`decorated), `HBox (`HSpacing (0.7), `VBox (
`HSpacing (25),
`VSpacing (0.2),
`Left (`Label (message)),
// text entry label
`InputField (`id (`user), `opt (`hstretch), _("&Username"),defaultuser),
`Password (`id(`passwd), `opt (`hstretch), Label::Password()),
machine_term,
`VSpacing (0.2),
`HBox (
`PushButton(`id(`ok), `opt(`default), Label::OKButton()),
`PushButton(`id(`cancel), Label::CancelButton())
),
`VSpacing (0.2)
), `HSpacing (0.7)));
if (SambaAD::ADS () != "" && what != `leave)
{
UI::ChangeWidget (`id (`machines), `Enabled, false);
}
UI::SetFocus (`id (`passwd));
any ret = nil;
string user = "";
string pass = "";
while (true)
{
ret = UI::UserInput();
user = (string)UI::QueryWidget(`id(`user), `Value);
pass = (string)UI::QueryWidget(`id(`passwd), `Value);
if (ret == `ok || ret == `cancel)
break;
if (ret == `acquire)
{
if (user == "" || pass == "")
{
// error popup
Popup::Error (_("User name and password are required
for listing the machine accounts."));
continue;
}
list<string> machines = SambaAD::GetMachines (domain, user, pass);
if (machines != nil)
{
list items = maplist (string m, sort (machines), ``(
`item (`id (m), m)));
items = prepend (items, default_entry);
UI::ReplaceWidget (`id (`rpcombo), `Left (
`ComboBox (`id (`machines), `opt (`hstretch),
_("&Machine Account"), items)
));
UI::ChangeWidget (`id (`machines), `Enabled, true);
}
}
}
map<string, string> result = (ret == `ok) ? $[
"user" : user,
"password" : pass
] : nil;
if (SambaAD::ADS () != "" && ret == `ok)
{
string machine = (string)UI::QueryWidget (`id (`machines), `Value);
if (machine != default_id)
result["machine"] = machine;
}
UI::CloseDialog();
return result;
}
/**
* If modified, ask for confirmation
* @return true if abort is confirmed
*/
define boolean ReallyAbort() ``{
return (Stage::cont() && !contains (WFM::Args (), "from_users")) ?
Popup::ConfirmAbort (`incomplete) :
(!Samba::GetModified() || Popup::ReallyAbort(true));
}
/**
* Check, if the workgroup is a domain or a workgroup. Uses caching to avoid long checks of a workgroup members.
*
* @param workgroup the workgroup to be checked
* @return symbol type of the workgroup: `joined_domain, `not_joined_domain, `workgroup or `domain if
* it is a domain, but the status is not known
*/
define symbol CheckWorkgroup( string workgroup ) ``{
// for autoyast, skip testing
if( Mode::config() ) return `workgroup;
symbol ret = nil;
// translators: text for busy pop-up
Popup::ShowFeedback ("", _("Verifying workgroup membership..."));
if (SambaNmbLookup::IsDomain(workgroup) || SambaAD::ADS () != "") {
// handle domain joining
boolean res = SambaNetJoin::Test(workgroup);
// we the host is already in domain, continue
if( res == true ) ret = `joined_domain;
else if( res != nil ) ret = `not_joined_domain;
else ret = `domain;
} else {
ret = `workgroup;
}
Popup::ClearFeedback ();
y2debug( "Check workgroup result: %1", ret );
return ret;
}
/**
* Leave an AD domain
*/
define symbol LeaveDomain (string workgroup)
{
// popup to fill in the domain leaving info; %1 is the domain name
map<string, string> passwd = passwordUserPopup (sformat(_("Enter the username and the password for leaving the domain %1."), workgroup),
"Administrator", workgroup, `leave);
// cancelled the domain leaving
if( passwd == nil ) return `fail;
// try to join the domain
string error = SambaNetJoin::Leave (
workgroup, passwd["user"]:nil, passwd["password"]:""
);
if (error != nil) {
Popup::Error(error);
return `fail;
}
return `ok;
}
define symbol JoinDomain(string workgroup)
{
// popup to fill in the domain joining info; %1 is the domain name
map<string, string> passwd = passwordUserPopup(sformat(_("Enter the username and the password for joining the domain %1."), workgroup)
+ "\n\n"
+ _("To join the domain anonymously, leave the text entries empty.") + "\n", "Administrator", workgroup, `join);
// cancelled the domain joining
if( passwd == nil ) return `fail;
// try to join the domain
string error = SambaNetJoin::Join (
workgroup, "member",
passwd["user"]:nil, passwd["password"]:"", passwd["machine"]:nil);
if (error != nil) {
Popup::Error(error);
return `fail;
}
// Translators: Information popup, %1 is the name of the domain
Popup::Message(sformat(_("Domain %1 joined successfully."), Samba::GetWorkgroup()));
return `ok;
}
/**
* Allow to join a domain. Uses result of @ref CheckWorkgroup to inform the user about the status.
*
* @param workgroup the workgroup to be joined
* @param status domain status returned by CheckWorkgroup
* @return symbol `ok on successful join (workgroup is always successful),
* `fail on error or user cancel
* `nojoin if user don't want to join
*/
define symbol AskJoinDomain( string workgroup, symbol status ) ``{
// for autoyast, skip testing
if( Mode::config() ) return `ok;
if( status == `workgroup || status == `joined_domain ) return `ok;
boolean res = false;
// allow to join the domain
if( status == `domain ) {
// we don't know the domain status
// translators: popup question, the domain status cannot be found out, ask user what to do
// %1 is the domain name
res = Popup::YesNo(sformat(_("Cannot automatically determine if this host\nis a member of the domain %1."), workgroup)
+ "\n\n" + sformat(_("Join the domain %1?"), workgroup) + "\n");
} else if( status == `not_joined_domain ) {
// translators: popup question, The workgroup is a domain in fact and the machine is not a member, ask user what to do.
// %1 is the domain name
res = Popup::YesNo(sformat(_("This host is not a member\nof the domain %1."), workgroup)
+ "\n\n" + sformat(_("Join the domain %1?"), workgroup) + "\n");
}
if (!res) {
return `nojoin;
}
return JoinDomain(workgroup);
}
/**
* Check if user shares already exist
* @param path to directory with shares
*/
define boolean SharesExist (string share_dir) {
if (!FileUtils::Exists (share_dir))
return false;
map out = (map) SCR::Execute (.target.bash_output, sformat ("/usr/bin/find %1 -type f | wc -l", share_dir));
integer count = tointeger (String::FirstChunk (out["stdout"]:"0", "\n"));
return (count != nil && count > 0);
}
/**
* ask user if existing shares should be removed
* @return true for removing
*/
define boolean AskForSharesRemoval () {
return !Popup::AnyQuestion (Popup::NoHeadline(),
// popup question
_("User shares already exist. Keep or delete these shares?"),
// button label
_("&Keep"),
// button label
_("&Delete"),
`focus_yes
);
// FIXME details
}
/**
* check if services should be stopped: only if there are more sections in
* smb.conf and if user confirms (bug #143908)
* @return true if smb+nmb should be stopped
*/
define boolean AskToStopServices () {
if (Service::Status("nmb") != 0 && Service::Status("smb") != 0)
return false;
if (size (SambaConfig::GetShares()) < 1)
return true;
// yes/no popup
return Popup::YesNo (_("Other Windows sharing services are available. Stop them as well?"));
}
/**
* return the term with hosts resolution support check box (fate#300971)
* @param hosts_resolution current value of hosts resolution in nsswitch.conf
*/
term HostsResolutionTerm (boolean hosts_resolution) {
// check box label
return `Left (`CheckBox (`id (`hosts_resolution),
_("&Use WINS for Hostname Resolution"), hosts_resolution));
}
/**
* Return help text for hosts resolution term
*/
string HostsResolutionHelp () {
// help text for "Use WINS for Hostname Resolution" check box label
return _("<p>If you want to use Microsoft Windows Internet Name Service (WINS) for name resolution, check <b>Use WINS for Hostname Resolution</b>.</p>");
}
/**
* return the term with DHCP support check box
* @param dhcp_support current value of DHCP support in smb.conf
*/
define term DHCPSupportTerm (boolean dhcp_support) {
// check box label
return `Left (`CheckBox (`id (`dhcp), _("Retrieve WINS server via &DHCP"), dhcp_support));
}
/**
* return the help text for DHCP support
*/
define string DHCPSupportHelp () {
// help text ("Retrieve WINS server via DHCP" is a checkbox label)
return _("<p>Check <b>Retrieve WINS server via DHCP</b> to use a WINS server provided by DHCP.</p>");
}
/**
* return the term with shares settings
* @param settings map with parameters to show in term
*/
define term SharesTerm (map settings) {
boolean allow = settings["allow_share"]:false;
string group = settings["group"]:settings["shares_group"]:"";
integer max = settings["max_shares"]:100;
boolean guest = settings["guest_access"]:false;
// frame label
string label = true ? _("Sharing by Users") :
// frame label
_("Sharing");
return `VBox (
`VSpacing (0.4),
// frame label
`Frame (label, `VBox (
`VSpacing (0.4),
`Left (`CheckBox(`id(`share_ch), `opt(`notify),
// checkbox label
_("&Allow Users to Share Their Directories"), allow)
),
haskey (settings, "guest_access") ?
`Left (`CheckBox(`id(`guest_ch), `opt(`notify),
// checkbox label
_("Allow &Guest Access"), guest))
: `VSpacing (0),
`HBox (`HSpacing (2), `VBox (
// texty entry label
`InputField (`id(`group), `opt(`hstretch),_("&Permitted Group"),
group),
// infield label
`IntField (`id(`max_shares),_("&Maximum Number of Shares"),
1, 99999, max)
)),
`VSpacing (0.2)
))
);
}
/**
* return the term with shares settings
* @param allow if shares are allowed
* @param group name of group owning the shares dir
* @param max maximum number of allowed shares
*/
define term GetSharesTerm (boolean allow, string group, integer max) {
y2warning ("GetSharesTerm is obsolete, use SharesTerm instead");
return SharesTerm ($[
"allow_share" : allow,
"shares_group" : group,
"max_shares" : max
]);
}
/**
* return the help text for shares
*/
define string SharesHelp () {
return
// membership dialog help (common part 3/4), %1 is separator (e.g. '\')
sformat (_("<p><b>Allow Users to Share Their Directories</b> enables members of the group in <b>Permitted Group</b> to share directories they own with other users. For example, <tt>users</tt> for a local scope or <tt>DOMAIN%1Users</tt> for a domain scope. The user also must make sure that the file system permissions allow access.</p>"), Samba::shares_separator) +
// membership dialog help (common part 3/4)
_("<p>With <b>Maximum Number of Shares</b>, limit the total amount of shares that may be created.</p>") +
// membership dialog help common part
_("<p>To permit access to user shares without authentication, enable <b>Allow Guest Access</b>.</p>");
}
/**
* return the help text for PAM Mount table
*/
string PAMMountHelp () {
// help text for PAM Mount table
return _("<p>In the table <b>Mount Server Directories</b>, you can specify server directories (such as home directory) which should be localy mounted when the user is logged in. If mounting should be user-specific, specify <b>User Name</b> for selected rule. Otherwise, the directory is mounted for each user. For more information, see pam_mount.conf manual page.</p>") +
// help text for PAM Mount table: example
_("<p>For example, you may use <tt>/home/%(DOMAIN_USER)</tt> value for <b>Remote Path</b>, <tt>~/</tt> value for <b>Local Mount Point</b> to mount the home directory, together with a value <tt>user=%(DOMAIN_USER)</tt> as a part of <b>Options</b>.</p>");
}
/* EOF */
}
ACC SHELL 2018