ACC SHELL
/**
* File: include/users/widgets.ycp
* Package: Configuration of users and groups
* Summary: Widgets definitions and helper functions
* Authors: Jiri Suchomel <jsuchome@suse.cz>
*
* $Id: widgets.ycp 54638 2009-01-15 07:35:55Z jsuchome $
*/
{
import "Autologin";
import "CWMTab";
import "Label";
import "Ldap";
import "Message";
import "Mode";
import "Package";
import "Popup";
import "Progress";
import "Report";
import "Stage";
import "String";
import "Summary";
import "Users";
import "UsersCache";
import "UsersLDAP";
import "UsersRoutines";
import "Wizard";
include "users/complex.ycp";
include "users/routines.ycp";
textdomain "users";
// values to MenuItem in Summary dialog
map userset_to_string = $[
// the type of user set
"system": _("&System Users"),
// the type of user set
"local": _("&Local Users"),
// the type of user set
"nis": _("&NIS Users"),
// the type of user set
"ldap": _("L&DAP Users"),
// the type of user set
"samba": _("Sam&ba Users"),
// the type of user set
"custom": _("&Custom")
];
// values to Label (no shortcut sign)
map userset_to_label = $[
// the type of user set
"system": _("System Users"),
// the type of user set
"local": _("Local Users"),
// the type of user set
"nis": _("NIS Users"),
// the type of user set
"ldap": _("LDAP Users"),
// the type of user set
"samba": _("Samba Users"),
// the type of user set
"custom": _("Custom")
];
// values to MenuItem in Summary dialog
map groupset_to_string = $[
// the type of group set
"system": _("&System Groups"),
// the type of group set
"local": _("&Local Groups"),
// the type of group set
"nis": _("&NIS Groups"),
// the type of group set
"ldap": _("L&DAP Groups"),
// the type of group set
"samba": _("Sam&ba Groups"),
// the type of group set
"custom": _("&Custom")
];
map groupset_to_label = $[
// the type of group set
"system": _("System Groups"),
// the type of group set
"local": _("Local Groups"),
// the type of group set
"nis": _("NIS Groups"),
// the type of group set
"ldap": _("LDAP Groups"),
// the type of group set
"samba": _("Samba Groups"),
// the type of group set
"custom": _("Custom")
];
// map with group names allowed for a default group
map<string,map<string,integer> > all_groupnames = $[];
// global values for authentication tab: ---------
// list of installed clients
list<string> installed_clients = [];
list<string> configurable_clients = [ "nis", "ldap", "kerberos", "samba" ];
// save if no more Available calls should be done (bug #225484)
boolean check_available = true;
map client_label = $[
// richtext label
"nis" : _("NIS"),
// richtext label
"ldap" : _("LDAP"),
// richtext label
"kerberos" : _("Kerberos"),
// richtext label
"samba" : _("Samba"),
];
// name of module to call
map call_module = $[
"samba": "samba-client",
];
// -------------
// function prototype
define symbol HandleFilterLine (string widget_id, map event);
/**
* Popup for choosing the password encryption method.
**/
define string EncryptionPopup() ``{
string method = Users::EncryptionMethod ();
// Help text for password expert dialog 1/5
string help_text = _("<p>
<b>This is for experts only.</b>
</p>");
// Help text for password expert dialog 2/5
help_text = help_text + _("<p>
Choose a password encryption method for local and system users.
<b>DES</b>, the Linux default method, works in all network environments, but it
restricts passwords to eight characters or less.
</p>
");
// Help text for password expert dialog 3/5
help_text = help_text + _("<p>
<b>MD5</b> allows longer passwords, so provides more security, but some
network protocols do not support this and you may have problems with NIS.
</p>");
// Help text for password expert dialog 4/5
help_text = help_text + _("<p>
<b>Blowfish</b> is similar to MD5, but uses a different algorithm
to encrypt passwords.
</P>");
// Help text for password expert dialog 5/5
help_text = help_text + _("<p>
As a general rule of thumb, use DES if you are unsure.
</p>");
UI::OpenDialog(
`VBox(
// Label
`Heading( _("Password Encryption") ),
`VSpacing( 0.7 ),
`HBox(
`HSpacing( 2 ),
`RadioButtonGroup(
// frame label
`Frame( _("Encryption Type"),
`VBox(
`VSpacing( 0.5 ),
// Radio buttons for password encryption: DES-crypt
`Left(`RadioButton(`id(`des), _("&DES (Linux default)"),
method == "des" ) ),
// Radio buttons for password encryption: MD5-crypt
`Left(`RadioButton(`id(`md5), _("&MD5"),
method == "md5" ) ),
// Radio buttons for password encryption: blowfish-crypt
`Left(`RadioButton(`id(`blowfish), _("&Blowfish"),
method == "blowfish" ) )
)
)),
`HSpacing( 2 )
),
`VSpacing( 0.5 ),
`HBox(
`HStretch(),
`HWeight(1, `PushButton(`id(`ok), `opt(`default, `key_F10),
Label::OKButton() )),
`HStretch(),
`HWeight(1, `PushButton(`id(`cancel), `opt (`key_F9),
Label::CancelButton())),
`HStretch(),
`HWeight(1, `PushButton(`id(`help), `opt (`key_F2),
Label::HelpButton() ) ),
`HStretch()
)
));
any button = nil;
do
{
button = UI::UserInput();
if ( button == `help )
{
Wizard::ShowHelp( help_text );
}
else if ( button == `ok )
{
if ( (boolean) UI::QueryWidget( `id(`des), `Value ) )
method = "des";
else if ( (boolean) UI::QueryWidget( `id(`md5), `Value ) )
method = "md5";
else if ( (boolean) UI::QueryWidget( `id(`blowfish), `Value ) )
method = "blowfish";
y2milestone( "Changing encryption method to %1", method );
}
} while ( button != `ok && button != `cancel );
UI::CloseDialog();
return method;
};
/**
* NIS server enabled together with non-DES encryption of passwords
* In these popup, ask user what to do.
*/
define symbol AskForNISServerEncryptionPopup (string encr) {
symbol ret = `ok;
// help text 1/3
string text = _("<p>
You have changed the default encryption for user passwords.</p>") +
// help text 2/3
_("<p>It seems that you are running a NIS server. In some network enviroments,
you could be unable to log in to a NIS client when a user password is
encrypted with a method other than DES.
</p>
") +
// help text 3/3
_("<p>Really use the selected method?</p>");
UI::OpenDialog (`opt(`decorated), `HBox(`VSpacing (14),
`VBox (
`HSpacing(50),
`RichText (`id(`rt), text),
`CheckBox (`id(`ch),`opt(`notify),Message::DoNotShowMessageAgain()),
`HBox (
`PushButton (`id(`ok),`opt(`key_F10), Label::YesButton()),
`PushButton (`id(`no),`opt(`key_F9), Label::NoButton())
)
))
);
do {
ret = (symbol) UI::UserInput();
}
while (!contains ([`cancel, `ok, `no], ret));
if (ret != `cancel)
{
Users::SetAskNISServerNotDES((boolean)UI::QueryWidget(`id(`ch),`Value));
}
UI::CloseDialog();
return ret;
}
/**
* Popup for configuration user/group filter for making the LDAP search
* @return modified?
*/
define boolean LDAPSearchFilterPopup () ``{
string default_user_f = UsersLDAP::GetDefaultUserFilter ();
string default_group_f = UsersLDAP::GetDefaultGroupFilter ();
string user_f = UsersLDAP::GetCurrentUserFilter ();
string group_f = UsersLDAP::GetCurrentGroupFilter ();
if (user_f == "")
user_f = default_user_f;
if (group_f == "")
group_f = default_group_f;
boolean ret = false;
// attributes are listed here, because during filter editing, the connection
// to LDAP server doesn't have to be run yet
list user_attributes = [
"objectClass", "loginShell", "gecos", "description", "cn", "uid",
"uidNumber", "gidNumber", "homeDirectory", "shadowLastChange",
"shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
"shadowExpire", "shadowFlag", "audio", "businessCategory", "carLicense",
"departmentNumber", "displayName", "employeeNumber", "employeeType",
"givenName", "homePhone", "homePostalAddress", "initials", "jpegPhoto",
"labeledUri", "mail", "manager", "mobile", "o", "pager", "photo",
"roomNumber", "secretary", "userCertificate", "x500uniqueIdentifier",
"preferredLanguage", "userSMIMECertificate", "userPKCS12", "title",
"x121Address", "registeredAddress", "destinationIndicator",
"preferredDeliveryMethod", "telexNumber", "teletexTerminalIdentifier",
"telephoneNumber", "internationalISDNNumber","facsimileTelephoneNumber",
"street", "postOfficeBox", "postalCode", "postalAddress",
"physicalDeliveryOfficeName", "ou", "st", "l", "seeAlso", "sn"
];
list group_attributes = [
"objectClass", "memberUid", "description", "gidNumber",
"businessCategory", "seeAlso", "owner", "ou", "o", "member", "cn"
];
list connectives = [
// combo box item
`item (`id("and"), _("AND")),
// combo box item
`item (`id("or"), _("OR"))
];
list equality = [ "=", "~=", "<=", ">=" ];
symbol curr_shown = UsersCache::GetCurrentSummary () == "users" ?
`users : `groups;
string help_text =
// helptext 1/4 - caption
_("<p><b>LDAP Search Filter Changes</b></p>") +
// helptext 2/4
_("<p>Here, extend the search filters for users and groups beyond the default search filters.</p>") +
// helptext 3/4
_("<p>With <b>Default</b>, load the default filter from the user and group
configuration modules saved on the LDAP server (values of 'suseSearchFilter' attributes).
If you are not connected yet, you are prompted for the password.</p>
") +
// helptext 4/4 (do not translate the value (written as <tt> font))
_("<p><b>Example:</b>
<br>With the user filter
<br>
<tt>(&(objectClass=posixAccount)(uid=u*))</tt>
<br>
only obtain users with a username beginning with 'u'.</p>
");
term contents = `HBox (`HSpacing(1.5), `VBox(
`HSpacing(70), // max 65 with help on left side...
`VSpacing(0.5),
`Left (`RadioButtonGroup (`VBox(
`Left (`RadioButton (`id (`users), `opt(`notify),
// radiobutton label
_("Search Filter for &Users"), curr_shown == `users)),
`Left (`RadioButton (`id (`groups), `opt(`notify),
// radiobutton label
_("Search Filter for &Groups"),curr_shown == `groups))
))),
`TextEntry (`id(`currf), "", curr_shown == `users ? user_f : group_f),
`VSpacing(0.5),
// frame label
`Frame (_("New Condition for Current Filter"), `HBox (
`HSpacing (0.5), `VBox (
`Left (`ComboBox (`id(`andor), "", connectives)),
`HBox (
`ReplacePoint (`id(`rpa),
// combobox label
`ComboBox (`id(`atrs), `opt(`editable), _("&Attribute"),
curr_shown == `users ?
user_attributes : group_attributes)
),
`HSpacing (),
`VBox (
`Label (""),
`ComboBox (`id(`eq), "", equality)
),
`HSpacing (),
// textentry label
`TextEntry (`id(`val), _("&Value"), "")
),
// pushbuttton label
`Right (`PushButton (`id(`addu), _("A&dd to Filter")))
),
`HSpacing (0.5)
)),
`VSpacing(),
`HBox (
`PushButton(`id(`ok),`opt(`default,`key_F10),Label::OKButton()),
`PushButton(`id(`cancel), `opt(`key_F9), Label::CancelButton()),
`PushButton(`id(`help), `opt(`key_F2), Label::HelpButton()),
// Pushbutton label
`PushButton(`id(`read), `opt(`key_F3), _("De&fault"))
),
`VSpacing (0.5)
), `HSpacing (1.5));
UI::OpenDialog (`opt(`decorated), contents);
symbol button = `notnext;
do
{
button = (symbol) UI::UserInput();
if ( button == `help )
{
Wizard::ShowHelp (help_text);
continue;
}
if ( button == `read )
{
if (Ldap::bind_pass == nil)
Ldap::SetBindPassword (Ldap::GetLDAPPassword (true));
if (Ldap::bind_pass != nil && UsersLDAP::ReadFilters() == "")
{
UI::ChangeWidget (`id (`currf), `Value, curr_shown == `users ?
UsersLDAP::GetDefaultUserFilter () :
UsersLDAP::GetDefaultGroupFilter ());
}
continue;
}
string curr_f = (string) UI::QueryWidget(`id (`currf), `Value);
if (button == `addu)
{
if ((string) UI::QueryWidget(`id (`val),`Value) == "")
{
// error popup
Popup::Error (_("Enter the value for the attribute."));
UI::SetFocus (`id(`val));
continue;
}
string new_value = sformat ("%1%2%3",
(string) UI::QueryWidget(`id (`atrs),`Value),
(string) UI::QueryWidget(`id (`eq),`Value),
(string) UI::QueryWidget(`id (`val),`Value));
string conn = (string) UI::QueryWidget(`id (`andor),`Value);
UI::ChangeWidget(`id (`currf), `Value,
UsersLDAP::AddToFilter (curr_f, new_value, conn));
}
if (button == `ok || button == `users || button == `groups)
{
if ((button == `groups || (button == `ok && curr_shown == `users))
&& user_f != curr_f)
{
string curr_user_f = curr_f;
if (curr_user_f == "")
{
// error popup
Popup::Error (_("Enter the value of the user filter."));
UI::SetFocus (`id(`currf));
button = `notnext;
continue;
}
if (!issubstring (tolower (curr_user_f),tolower(default_user_f))
// yes/no popup question
&& !Popup::YesNo (_("The new user filter does not contain the default user filter.
Really use it?
")))
{
UI::SetFocus (`id(`currf));
button = `notnext;
continue;
}
user_f = curr_user_f;
}
if ((button == `users || (button == `ok && curr_shown == `groups))
&& group_f != curr_f)
{
string curr_group_f = curr_f;
if (curr_group_f == "")
{
// error popup
Popup::Error (_("Enter the value of the group filter."));
UI::SetFocus (`id(`currf));
button = `notnext;
continue;
}
if(!issubstring(tolower(curr_group_f),tolower(default_group_f)))
{
// yes/no popup question
if (!Popup::YesNo (_("The new group filter does not contain the default group filter.
Really use it?
")))
{
UI::SetFocus (`id(`currf));
button = `notnext;
continue;
}
}
group_f = curr_group_f;
}
if (button == `ok)
{
// checks are OK, let's update the values now
if (user_f != UsersLDAP::GetCurrentUserFilter ())
{
UsersLDAP::SetCurrentUserFilter (user_f);
ret = true;
}
if (group_f != UsersLDAP::GetCurrentGroupFilter())
{
UsersLDAP::SetCurrentGroupFilter (group_f);
ret = true;
}
}
else
{
UI::ChangeWidget (`id (curr_shown), `Value, false);
curr_shown = (curr_shown == `users) ? `groups : `users;
UI::ChangeWidget (`id (curr_shown), `Value, true);
UI::ChangeWidget (`id (`currf), `Value, curr_shown == `users ?
user_f : group_f);
UI::ReplaceWidget (`id(`rpa),
// combobox label
`ComboBox (`id(`atrs), `opt(`editable), _("&Attribute"),
curr_shown == `users ?
user_attributes : group_attributes)
);
}
}
} while ( button != `ok && button != `cancel );
UI::CloseDialog();
return ret;
}
/**
* Popup for Login settings (Auotolgin feature, login without passwords)
* @return modified?
**/
define boolean AutologinPopup() ``{
string help_text =
// helptext 0/3 - caption
_("<p><b>Login Settings</b></p>") +
// helptext 1/3 - general info
_("<p>
The features described below are only available if you are using KDM or GDM as the login manager.
</p>
") +
// helptext 2/3
_("<p><b>Auto Login</b><br>
By setting <b>Auto Login</b>, skip the login procedure. The user chosen from the list is logged in automatically.</p>
") +
// helptext 3/3
_("<p><b>Passwordless Logins</b><br>
If this option is checked, all users are allowed to log in without entering
passwords. Otherwise, you are asked for the password even if you set a user to log in automatically.</p>
");
boolean ret = false;
string user = Autologin::user;
boolean pw_less = Autologin::pw_less;
boolean auto_used = (user != "");
// TODO check if nis/ldap users were read?
list usernames = UsersCache::GetUsernames ("local");
UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
`VBox(
`HSpacing(40),
`VSpacing(0.5),
// dialog label
`Heading(_("Display Manager Login Settings")),
`HBox(
`HSpacing (0.5),
`VBox(
`VSpacing(0.5),
`Left(`CheckBox (`id(`auto),`opt (`notify),
// checkbox label
_("&Auto Login"), auto_used)),
`VSpacing(0.2),
`HBox (
`HSpacing (4), // move text under the checkbox
`Left(`ComboBox (`id(`autouser),
// textentry label
_("&User to Log In"), usernames))
),
`VSpacing(0.5),
`Left(`CheckBox (`id(`pw_less),
// checkbox label
_("Password&less Logins"), pw_less)),
`VSpacing(0.5)
),
`HSpacing(0.5)
),
`VSpacing(0.5),
`HBox(
`PushButton(`id(`ok),`opt(`default,`key_F10),Label::OKButton()),
`PushButton(`id(`cancel), `opt(`key_F9), Label::CancelButton()),
`PushButton(`id(`help), `opt(`key_F2), Label::HelpButton())
),
`VSpacing(0.5)),
`HSpacing(1.5)
));
if (user != "")
UI::ChangeWidget (`id (`autouser), `Value, user);
UI::ChangeWidget (`id (`autouser), `Enabled, auto_used);
symbol button = nil;
do
{
button = (symbol) UI::UserInput();
if ( button == `help )
{
Wizard::ShowHelp( help_text );
}
if ( button == `auto )
{
auto_used = (boolean) UI::QueryWidget (`id(`auto), `Value);
UI::ChangeWidget (`id (`autouser), `Enabled, auto_used);
}
} while ( !contains ([`ok, `cancel, `abort], button));
if (button == `ok)
{
user = (auto_used) ?(string)UI::QueryWidget (`id(`autouser), `Value):"";
pw_less = (boolean) UI::QueryWidget (`id(`pw_less), `Value);
if (user != Autologin::user || pw_less != Autologin::pw_less)
{
ret = true;
Autologin::used = auto_used;
Autologin::user = user;
Autologin::pw_less = pw_less;
Autologin::modified = true;
}
}
UI::CloseDialog();
return ret;
};
/**
* Popup for deleting user
* @return symbol for sequencer
*/
define symbol DeleteUserPopup() ``{
boolean delete = true;
boolean delete_home = false;
string type = UsersCache::GetUserType ();
map user = Users::GetCurrentUser ();
string username = user["uid"]:"";
string home = user["org_user","homeDirectory"]:user["org_homeDirectory"]:user["homeDirectory"]:"";
integer uid = -1;
any uid_a = user["org_user","uidNumber"]:user["org_uidNumber"]:user["uidNumber"]:"-1";
if (is (uid_a, string))
uid = tointeger (uid_a);
else uid = (integer) uid_a;
if (type == "nis")
{
// error popup
Report::Message (sformat (_("Cannot delete the user %1. It must be done on the NIS server."), username));
return nil;
}
if (UserLogged (username))
{
// error popup
Report::Error(_("You cannot delete this user, because the user is
currently logged in.
Log the user out first."));
delete = false;
return nil;
}
boolean no_home = false;
// check if dir exists with this owner
map stat = (map)SCR::Read (.target.stat, home);
string crypted_img = UsersRoutines::CryptedImagePath (username);
if (crypted_img != "") // check crypted dir image
{
stat = (map)SCR::Read (.target.stat, crypted_img);
}
if ((type == "ldap" && !Ldap::file_server) || (stat["uid"]:-1 != uid))
{
no_home = true;
}
// if the user want to delete a system user
if (type == "system")
{
// yes-no popup headline
if(! Popup::YesNoHeadline(_("Selected User Is System User"),
// yes-no popup contents
_("Really delete this system user?")))
{
delete = false;
}
}
else
{
if (home != "" && !no_home)
{
term contents = `HBox(
`HSpacing(3),
`VBox (`VSpacing(1),
`Left (
// question popup. %1 is username
`Heading(sformat(_("Delete the user %1?"), username ))),
`VSpacing(0.5),
`Left (`CheckBox(`id(`delete_home),
// checkbox label
sformat(_("Delete &Home Directory
%1
"), home )
)),
`VSpacing(1),
`HBox (
`Bottom(`PushButton(`id(`ok),`opt(`key_F10),
Label::YesButton() )),
`Bottom(`PushButton(`id(`cancel), `opt(`key_F9),
Label::NoButton()))
)
),
`HSpacing(3)
);
UI::OpenDialog(`opt( `decorated ), contents );
any ret = UI::UserInput();
if (ret != `ok)
delete = false;
delete_home = (boolean) UI::QueryWidget (`id(`delete_home), `Value);
UI::CloseDialog();
}
else
{
// yes-no popup. %1 is username
if( ! Popup::YesNo(sformat(_("
Really delete the user %1?
"), username )))
{
delete = false;
}
}
}
if (delete)
{
Users::DeleteUser (delete_home);
return `delete;
}
return nil;
}
/**
* Popup for deleting group
* @return symbol for sequencer
*/
define symbol DeleteGroupPopup() ``{
boolean delete = true;
string type = UsersCache::GetGroupType ();
map group = Users::GetCurrentGroup ();
string member_attribute = UsersLDAP::GetMemberAttribute ();
// if no user is in this group
if (group["userlist"]:$[] == $[] &&
group["more_users"]:$[] == $[] &&
group[member_attribute]:$[] == $[])
{
//if the group is a system group ask the user ..
if (type == "system")
{
// yes-no popup headline
if(!Popup::YesNoHeadline(_("System Group"),
/// yes-no popup contents
_("Really delete this system group?")))
{
return nil;
}
}
else
{
// yes-no popup, %1 si group name
if (! Popup::YesNo(sformat(_("
Really delete the group %1?
"), group["cn"]:"")))
{
return nil;
}
}
}
else
{
// warning popup
Popup::Warning(_("You cannot delete this group because
there are users in the group.
Remove these users from the group first.
"));
return nil;
}
Users::DeleteGroup ();
return `delete;
}
/**
* Dialog for definition of customized view
* @param what "users" or "groups"
* @return true if customs were odified
*/
define boolean CustomizePopup (string what) ``{
term view = `VBox();
string label = "";
list<string> sets = [];
list custom_sets = [];
map set_to_string = $[];
if (what == "users")
{
sets = filter (string set, Users::GetAvailableUserSets (),
``(set != "custom"));
custom_sets = Users::GetUserCustomSets ();
set_to_string = userset_to_string;
// Frame label
label = _("User List View");
}
else
{
sets = filter (string set, Users::GetAvailableGroupSets (),
``(set != "custom"));
custom_sets = Users::GetGroupCustomSets ();
set_to_string = groupset_to_string;
// Frame label
label = _("Group List View");
}
foreach (string set, sets, ``{
view = add (view, `VSpacing(0.5));
if ( contains (custom_sets, set) )
view = add (view,
`Left(`CheckBox(`id(set), set_to_string [set]:"", true)));
else
view = add (view,
`Left(`CheckBox(`id(set), set_to_string [set]:"", false)));
});
view = add (view, `VSpacing(0.5));
UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
`VBox(
`HSpacing(40),
`VSpacing(0.5),
`Frame(label, view),
`VSpacing(0.5),
`HBox(
`PushButton(`id(`ok),`opt(`default,`key_F10),Label::OKButton()),
`PushButton(`id(`cancel), `opt(`key_F9), Label::CancelButton())
),
`VSpacing(0.5)),
`HSpacing(1.5)
));
any ret = UI::UserInput();
boolean modified = false;
list<string> new_customs = [];
if (ret == `ok)
{
foreach (string set, sets, ``{
if ((boolean)UI::QueryWidget(`id(set), `Value))
{
new_customs = add (new_customs, set);
if (! contains (custom_sets, set)) modified = true;
}
else
{
if (contains (custom_sets, set)) modified = true;
}
});;
}
UI::CloseDialog();
if (modified)
{
if (contains (new_customs, "ldap") && Ldap::bind_pass == nil)
{
Ldap::SetBindPassword (Ldap::GetLDAPPassword (true));
if (Ldap::bind_pass == nil || UsersLDAP::ReadSettings () != "")
{
new_customs = filter (string set, new_customs,``(set !="ldap"));
}
}
modified = Users::ChangeCustoms (what, new_customs);
}
return modified;
}
/**
* When there are more users/groups shown, choose which type should be created
* after `add click
*/
define string ChooseTypePopup (list<string> sets, string what) ``{
map set_to_string = $[
// type of user/group
// (item of list with the headline 'Choose the type of user to add')
"local" : _("Local"),
// type of user/group
// (item of list with the headline 'Choose the type of user to add')
"ldap" : _("LDAP"),
// type of user/group
// (item of list with the headline 'Choose the type of user to add')
"system": _("System")
];
sets = filter (string set, sets, ``(set != "nis"));
string ret = sets[0]:"local";
string label = (what == "user") ?
// label
_("User Type") :
// label
_("Group Type");
if (size (sets) < 2) return ret;
term rbs = `VBox ();
foreach (string set, sets, ``{
rbs = add (rbs, `Left (
`RadioButton (`id (set), set_to_string [set]:set, set == ret)));
});
UI::OpenDialog(`opt(`decorated), `HBox(`HSpacing(1.5),
`VBox(
`HSpacing(40),
`VSpacing(0.5),
`Left (`Label (label)),
`VSpacing(0.5),
`Left (`RadioButtonGroup (rbs)),
`VSpacing(0.5),
`HBox(
`PushButton(`id(`ok),`opt(`default,`key_F10),Label::OKButton()),
`PushButton(`id(`cancel), `opt(`key_F9), Label::CancelButton())
),
`VSpacing(0.5)),
`HSpacing(1.5)
));
any r = UI::UserInput();
foreach (string set, sets, ``{
if ( (boolean) UI::QueryWidget( `id(set), `Value ) )
ret = set;
});
UI::CloseDialog();
if (r == `cancel) return "";
return ret;
}
//================================================================
define list GetSetsItems (string set) ``{
list items = [];
if (set == "users")
{
foreach (string set, Users::GetAvailableUserSets (), ``{
items = add (items, `item (`id(set), userset_to_string [set]:""));
});
// menubutton item
items = add (items, `item (`id(`customize), _("Customi&ze Filter...")));
}
else
{
foreach (string set, Users::GetAvailableGroupSets (), ``{
items = add (items, `item (`id(set), groupset_to_string [set]:""));
});
// menubutton item
items = add (items, `item (`id(`customize), _("Customi&ze Filter...")));
}
return items;
}
/**
* return the list of menu items of "Expert Options" menubutton
*/
define list GetExpertList () ``{
list expert_list = [];
if (Autologin::available)
{
expert_list = add (expert_list,
// menubutton label
`item(`id(`autologinconf), _("&Login Settings")));
}
if (!Mode::config ())
{
expert_list = prepend (expert_list,
// menubutton label
`item (`id(`enc), _("Password &Encryption"))
);
if (!Stage::cont ())
{
expert_list = add (expert_list,
// menubutton label
`item(`id(`save), _("&Write Changes Now")));
}
}
return expert_list;
}
/**
* return the list of menu items for LDAP expert options
*/
define list GetLDAPExpertList () ``{
list expert_list = [ ];
if (!Mode::config () && Users::LDAPAvailable () && !Users::LDAPModified ())
{
expert_list = add (expert_list,
// menubutton label
`item(`id(`ldapfilter), _("LDAP &Search Filter")));
expert_list = add (expert_list,
// menubutton label
`item(`id(`ldapconf),_("L&DAP User and Group Configuration")));
}
return expert_list;
}
//================================================================
//----------------- some help texts ------------------------------
/**
* First part of the help text.
* @return string help text
*/
define string help_main_start()``{
// help text 1/1
return _("<p>
Linux is a multiuser system. Several different users can be logged in to the
system at the same time. To avoid confusion, each user must have
a unique identity. Additionally, every user belongs to at least one group.
</p>
");
}
/**
* Last part of the help text.
* @return string help text
*/
define string help_main_end()``{
string button = Stage::cont () ? Label::NextButton () :
Label::FinishButton ();
// help text 1/3
return _("<p>
Users and groups are arranged in various sets. Change the set currently shown in the table with <b>Set Filter</b>.
Customize your view with <b>Customize Filter</b>.</p>
") +
// help text 2/3
_("<p>
Click <b>Expert Options</b> to edit various expert settings, such as
password encryption type, user authentication method, default values for new
users, or login settings. With <b>Write Changes Now</b>, save
all changes made so far without exiting the configuration module.</p>
") +
// help text 3/3, %1 is translated button label
sformat(_("<p>
To save the modified user and group settings to your system, press
<b>%1</b>.
</p>
"), String::RemoveShortcut (button));
}
/**
* Help for UsersDialog.
* @return string help text
*/
define string UsersDialogHelp() ``{
// help text 1/4
return help_main_start() + _("
<p>
Use this dialog to get information about existing users and add or modify
users.
</p>
") +
// help text 2/4
_("<p>
To shift to the group dialog, select <b>Groups</b>.
</p>
") +
// help text 3/4
_("
<p>
To create a new user, click <b>Add</b>.
</p>
") +
// help text 4/4
_("<p>
To edit or delete an existing user, select one user from the list and
click <b>Edit</b> or <b>Delete</b>.
</p>
") +
help_main_end();
}
/**
* Help for usersGroups.
* @return string help text
*/
define string GroupsDialogHelp()``{
return help_main_start() +
// help text 1/4
_("
<p>
Use this dialog to get information about existing groups and add or modify groups.
</p>
") +
// help text 2/4
_("<p>
To shift to the user dialog, select <b>Users</b>.
</p>
") +
// help text 3/4
_("
<p>
To create a new group, click <b>Add</b>.
</p>
") +
// help text 4/4
_("<p>
To edit or delete an existing group, select one group from the list and
click <b>Edit</b> or <b>Delete</b>.
</p>
") + help_main_end();
}
//================================================================
/**
* Validation function for the default value of account expiration
*/
define boolean ValidateExpire (string key, map event) {
string new_exp_date = (string) UI::QueryWidget(`id (key),`Value);
if (new_exp_date != "" && !regexpmatch (new_exp_date,
"[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]"))
{
// popup label - don't reorder the letters YYYY-MM-DD
// The date must stay in this format
Report::Error (_("The expiration date must be in the format YYYY-MM-DD."));
UI::SetFocus(`id (key));
return false;
}
return true;
}
/**
* Validation function for home directory skeleton directory
*/
define boolean ValidateSkeleton (string key, map event) {
string new_skel = (string) UI::QueryWidget (`id (key), `Value);
if (SCR::Read(.target.dir, new_skel) == nil)
{
// popup error label
Report::Error(_("The entered home directory skeleton is not a directory.
Try again.
"));
UI::SetFocus(`id (key));
return false;
}
return true;
}
/**
* Validation function for the default home prefix
*/
define boolean ValidateHomePrefix (string key, map event) {
string new_home = (string) UI::QueryWidget (`id(key), `Value);
if (SCR::Read (.target.dir, new_home) == nil)
{
if (SCR::Read (.target.size, new_home) != -1)
{
// error message
Report::Error(_("The entered path prefix for home is not a directory.
Try again.
"));
UI::SetFocus (`id (key));
return false;
}
else
{
// yes/no popup
if (Popup::YesNo (_("The selected directory does not exist.
Create it now?
")))
{
if (!(boolean) SCR::Execute(.target.mkdir, new_home))
{
Report::Error (Message::UnableToCreateDirectory (new_home));
UI::SetFocus (`id (key));
return false;
}
}
else
{
UI::SetFocus (`id (key));
return false;
}
}
}
return true;
}
/**
* Validation function for the value of the default list of groups
*/
define boolean ValidateGroupList (string key, map event) {
map<string,integer> groups = Users::GetDefaultGrouplist ("local");
string grouplist = mergestring (
(list<string>) maplist (string g,integer i, groups, ``(g)), ",");
string new_grouplist = (string) UI::QueryWidget (`id(key), `Value);
if (new_grouplist != grouplist)
{
list<string> l_grouplist = [];
list<string> dont_exist = [];
foreach (string g, splitstring (new_grouplist, ","), {
// check for group existence
if (all_groupnames["local", g]:0 == 0 &&
all_groupnames["system", g]:0 == 0)
dont_exist = (list<string>) union (dont_exist, [g]);
// filter out the duplicates
else l_grouplist = (list<string>) union (l_grouplist, [g]);
});
if (dont_exist != [])
{
// error message
Report::Error(sformat (_("These groups do not exist in your system:
%1
Try again.
"), mergestring (dont_exist, ",")));
UI::SetFocus (`id ("groups"));
return false;
}
new_grouplist = mergestring (l_grouplist, ",");
UI::ChangeWidget (`id ("groups"), `Value, new_grouplist);
}
return true;
}
/**
* Validation function for the default login shell
*/
define boolean ValidateShell (string key, map event) {
string new_shell = (string) UI::QueryWidget (`id (key), `Value);
if (! contains (Users::AllShells (), new_shell))
{
// Yes-No popup
return Popup::YesNo (_("If you select a nonexistent shell, the user
may be unable to log in. Continue?
"));
}
return true;
}
/**
* Initialize all the values in the dialog with new user defaults
*/
define void InitDefaults (string key) {
map defaults = Users::GetLoginDefaults ();
list items = [];
all_groupnames = UsersCache::GetAllGroupnames ();
string defaultgroup = Users::GetDefaultGroupname ("local");
foreach (string grouptype, map<string,integer> groupmap, all_groupnames,
{
// only local sets
if (!contains (["local", "system"], grouptype))
return;
foreach (string group, integer val, groupmap, {
if (group == defaultgroup)
items = add (items, `item (`id(group), group, true));
else
items = add (items, `item( `id(group), group));
});
});
UI::ChangeWidget (`id ("defaultgroup"), `Items, items);
UI::ChangeWidget (`id ("shell"), `Items, Users::AllShells ());
UI::ChangeWidget(`id ("shell"), `Value, Users::GetDefaultShell ("local"));
map<string,integer> groups = Users::GetDefaultGrouplist ("local");
string grouplist = mergestring (
(list<string>) maplist (string g,integer i, groups, ``(g)), ",");
UI::ChangeWidget (`id ("groups"), `Value, grouplist);
UI::ChangeWidget (`id ("home"), `Value, defaults["home"]:"/home");
UI::ChangeWidget (`id ("skel"), `Value, defaults["skel"]:"/etc/skel");
UI::ChangeWidget (`id ("inactive"), `Value,
tointeger (defaults["inactive"]:"0"));
string expire = defaults["expire"]:"";
string exp_date = "";
if (expire != "0" && expire != "")
{
// 'expire' is expected to be number of days since 1970-01-01
map out = (map) SCR::Execute (.target.bash_output, sformat (
"date --date='1970-01-01 00:00:01 %1 days' ", expire) +
"+\"%Y-%m-%d\"");
exp_date = deletechars (out["stdout"]:"", "\n");
}
UI::ChangeWidget (`id ("expire"), `Value, exp_date);
UI::ChangeWidget (`id ("umask"), `Value, defaults["umask"]:"");
UI::ChangeWidget (`id ("umask"), `InputMaxLength, 3);
}
/**
* Store all the values from the dialog with new user defaults
* (when leaving the dialog)
*/
define void StoreDefaults (string key, map event) {
map defaults = Users::GetLoginDefaults ();
map<string,string> new_defaults = $[];
foreach (string key, [ "home", "shell", "skel", "inactive", "umask" ], {
any val = UI::QueryWidget (`id (key), `Value);
if (is (val, integer))
val = sformat("%1", val);
if (defaults[key]:nil != val)
{
new_defaults[key] = (string)val;
}
});
string new_grouplist = (string) UI::QueryWidget (`id ("groups"), `Value);
if (sort (splitstring (defaults["groups"]:"", ",")) !=
sort (splitstring (new_grouplist, ",")))
{
new_defaults["groups"] = new_grouplist;
}
string new_exp_date = (string) UI::QueryWidget(`id ("expire"),`Value);
string new_expire = defaults["expire"]:"";
if (new_exp_date == "")
new_expire = "";
else
{
map out = (map) SCR::Execute(.target.bash_output,
sformat("date --date='%1 UTC' ", new_exp_date) + "+%s");
string seconds_s = deletechars (out["stdout"]:"0", "\n");
if (seconds_s != "")
{
integer days = (tointeger(seconds_s))/ (60*60*24);
new_expire = sformat("%1", days);
}
}
if (new_expire != defaults["expire"]:"")
new_defaults["expire"] = new_expire;
string new_defgroup = (string)UI::QueryWidget (`id("defaultgroup"),`Value);
if (Users::GetDefaultGroupname ("local") != new_defgroup)
{
map g = Users::GetGroupByName (new_defgroup, "");
new_defaults["group"] = sformat ("%1", GetInt (g["gidNumber"]:nil,
Users::GetDefaultGID ("local")));
}
if (new_defaults != $[])
{
Users::SetLoginDefaults (new_defaults, new_defgroup);
}
}
/**
* universal handler for directory browsing
*/
symbol HandleBrowseDirectory (string key, map event) {
if (event["ID"]:nil != key) return nil;
string val = substring (key, 7);
string current = (string) UI::QueryWidget (`id (val), `Value);
if (current == nil) current = "";
// directory location popup label
string dir = UI::AskForExistingDirectory (current, _("Path to Directory"));
if (dir!= nil)
{
UI::ChangeWidget (`id (val), `Value, dir);
}
return nil;
}
/**
* Handle the switch between tabs (load set of items for users or groups)
*/
define void InitTabUsersGroups (string widget_id) {
string current_summary = UsersCache::GetCurrentSummary ();
if (current_summary == CWMTab::CurrentTab ())
{
// tab shows already current set
return;
}
else
UsersCache::ChangeCurrentSummary ();
}
/**
* Initialize the contents of Summary Table widget
*/
define void SummaryTableInit (string widget_id) ``{
list items = [];
string current_summary = UsersCache::GetCurrentSummary ();
if (current_summary == "users")
{
items = UsersCache::GetUserItems ();
UI::ReplaceWidget (`id(`rptable),
`Table (`id("table"), `opt(`notify), `header(
// table header
_("Login"),
// table header
_("Name"),
// table header
_("UID"),
// table header
_("Groups")), [] )
);
}
else
{
items = UsersCache::GetGroupItems ();
UI::ReplaceWidget (`id(`rptable),
`Table (`id("table"), `opt(`notify), `header(
// table header
_("Group Name"),
// table header
_("Group ID"),
// table header
_("Group Members")), [] )
);
}
UI::ChangeWidget (`id(widget_id), `Items, items);
if (size (items) > 0)
{
UI::SetFocus (`id(widget_id));
string focusline = UsersCache::GetCurrentFocus ();
if (focusline != nil)
UI::ChangeWidget (`id(widget_id), `CurrentItem, focusline);
}
UI::ReplaceWidget (`id (`rpexpert),
// Menu Buton label
`MenuButton (`id(`expertlist), _("E&xpert Options"), union (
GetExpertList(), GetLDAPExpertList ()))
);
}
/**
* Handler for users/groups summary table
*/
define symbol HandleSummaryTable (string widget_id, map event) {
any ev_id = event["ID"]:nil;
string current_summary = UsersCache::GetCurrentSummary ();
if (ev_id == "table")
{
ev_id = `edit;
}
if (ev_id == `new)
{
string error = "";
if (current_summary == "users")
{
list<string> current_users = Users::GetCurrentUsers();
if (size (current_users) > 1)
{
string set = ChooseTypePopup (current_users, "user");
if (set == "") return nil;
current_users = filter (string u, current_users, ``(u != set));
current_users = prepend (current_users, set);
Users::SetCurrentUsers (current_users);
}
error = Users::AddUser ($[]);
}
else
{
list<string> current_groups = Users::GetCurrentGroups();
if (size (current_groups) > 1)
{
string set = ChooseTypePopup (current_groups, "group");
if (set == "") return nil;
current_groups = filter (string u, current_groups,``(u != set));
current_groups = prepend (current_groups, set);
Users::SetCurrentGroups (current_groups);
}
error = Users::AddGroup ($[]);
}
if (error != "")
{
Popup::Error (error);
return nil;
}
}
if (ev_id == `edit || ev_id == `delete)
{
string selected = (string)UI::QueryWidget (`id("table"),`CurrentItem);
if (selected != nil)
{
string error = "";
UsersCache::SetCurrentFocus (selected);
if (current_summary == "users")
{
Users::SelectUserByName (selected);
if (ev_id == `delete)
ev_id = DeleteUserPopup ();
else
{
error = Users::EditUser ($[]);
}
}
else
{
Users::SelectGroupByName (selected);
if (UsersCache::GetGroupType () == "nis")
{
// error popup
Report::Message (_("NIS groups can only be
modified and deleted on the server.
"));
ev_id = nil;
}
if (ev_id == `delete)
ev_id = DeleteGroupPopup();
else
{
error = Users::EditGroup ($[]);
}
}
if (error != "")
{
Report::Error (error);
return nil;
}
}
else
{
// error popup
Report::Message(_("Select an entry from the table."));
return nil;
}
}
if (ev_id == `enc)
{
string enc = EncryptionPopup ();
if (enc != Users::EncryptionMethod ())
{
if (enc != "des" &&
Users::NISMaster () && !Users::NotAskNISServerNotDES ())
{
if (AskForNISServerEncryptionPopup (enc) != `ok)
return nil;
}
Users::SetEncryptionMethod (enc);
}
return nil;
}
if (ev_id == `autologinconf)
{
AutologinPopup();
return nil;
}
if (ev_id == `save)
{
if (!Users::Modified ())
{
//popup message (user wants to save but there is no modification)
Popup::Message (_("There are no changes to save."));
return nil;
}
Wizard::CreateDialog ();
Wizard::SetDesktopIcon("users");
any ret = WriteDialog (true);
Wizard::CloseDialog ();
y2milestone ("WriteDialog returned %1", ret);
// LDAP expert options could be available again
SummaryTableInit ("table");
return nil;
}
if (ev_id == `ldapfilter)
{
// change of search filter (only when LDAP was not modified yet)
if (LDAPSearchFilterPopup() && !Users::LDAPModified())
{
Users::SetLDAPNotRead (true);
list current = (current_summary == "users") ?
Users::GetCurrentUsers () : Users::GetCurrentGroups ();
if (contains (current, "ldap"))
{
// simulate the action "show LDAP users"
HandleFilterLine (widget_id, $["ID":"ldap"]);
}
// now update the other list (not current_summary)
current = (current_summary == "users") ?
Users::GetCurrentGroups () : Users::GetCurrentUsers ();
if (contains (current, "ldap"))
{
// customize view is lost... TODO
if (current_summary == "users")
Users::ChangeCurrentGroups ("ldap");
else
Users::ChangeCurrentUsers ("ldap");
}
}
return nil;
}
if (ev_id == `ldapconf)
{
any ret = WFM::CallFunction ("ldap_config", ["late_dialog"]);
if (ret == `next && Ldap::ldap_modified)
{
if (!Users::LDAPNotRead () &&
// yes/no popup (data were changed)
Popup::YesNo (_("Reread all data from LDAP server?")))
{
// read all LDAP configuration again!
Users::SetLDAPNotRead (true);
UsersLDAP::SetFiltersRead (false);
UsersLDAP::SetInitialized (false);
list current = (current_summary == "users") ?
Users::GetCurrentUsers () : Users::GetCurrentGroups ();
if (contains (current, "ldap"))
{
// simulate the action "show LDAP users"
HandleFilterLine (widget_id, $["ID":"ldap"]);
}
// now update the other list (not current_summary)
current = (current_summary == "users") ?
Users::GetCurrentGroups () : Users::GetCurrentUsers ();
if (contains (current, "ldap"))
{
// customize view is lost... TODO
if (current_summary == "users")
Users::ChangeCurrentGroups ("ldap");
else
Users::ChangeCurrentUsers ("ldap");
}
}
Ldap::ldap_modified = false;
}
return nil;
}
if (! is (ev_id, symbol))
{
y2error ("strange ev_id value: %1", ev_id);
return nil;
}
return (symbol) ev_id;
}
/**
* Initialize the value of the label with current filter and filter selection
*/
define void InitFilterLine (string widget_id) {
string current_summary = UsersCache::GetCurrentSummary ();
string curr = "";
if (current_summary == "users")
{
if (UsersCache::CustomizedUsersView ())
curr = userset_to_label["custom"]:"";
else
{
list current_users = Users::GetCurrentUsers ();
curr = userset_to_label[current_users[0]:"custom"]:"";
}
}
else
{
if (UsersCache::CustomizedGroupsView ())
curr = groupset_to_label["custom"]:"";
else
{
list current_groups = Users::GetCurrentGroups ();
curr = groupset_to_label[current_groups[0]:"custom"]:"";
}
}
UI::ReplaceWidget (`id(`rpfilter), `HBox(
// label, e.g. 'Filter: Local Users', 'Filter: Custom'
`Left (`Label (`id(`current_filter), sformat (_("Filter: %1"), curr))),
// MenuButton label
`MenuButton (`id(`sets), `opt(`key_F2), _("&Set Filter"),
GetSetsItems (current_summary))
));
}
/**
* Handler for events generated by Set Filter widget
*/
define symbol HandleFilterLine (string widget_id, map event) {
any ev_id = event["ID"]:nil;
string current_summary = UsersCache::GetCurrentSummary ();
if (current_summary == "users" && is (ev_id,string) &&
contains (Users::GetAvailableUserSets (), (string) ev_id))
{
if (ev_id == "ldap" && Ldap::bind_pass == nil)
{
Ldap::SetBindPassword (Ldap::GetLDAPPassword (true));
if (Ldap::bind_pass == nil)
return nil;
}
boolean popup = false;
if ((ev_id == "ldap" && Users::LDAPNotRead ()) ||
(ev_id == "nis" && Users::NISNotRead ()))
{
UI::OpenDialog (`opt(`decorated ),
// wait popup
`Label(_("Reading sets of users and groups. Please wait...")));
popup = true;
}
if (Users::ChangeCurrentUsers ((string) ev_id))
{
if (popup)
{
UI::CloseDialog ();
popup = false;
}
UsersCache::SetCustomizedUsersView (ev_id == "custom");
SummaryTableInit ("table");
InitFilterLine (widget_id);
InitTabUsersGroups ("");
}
if (popup) UI::CloseDialog ();
return nil;
}
if (current_summary == "groups" && is (ev_id,string) &&
contains (Users::GetAvailableGroupSets (), (string) ev_id))
{
if (ev_id == "ldap" && Ldap::bind_pass == nil)
{
Ldap::SetBindPassword (Ldap::GetLDAPPassword (true));
}
boolean popup = false;
if ((ev_id == "ldap" && Users::LDAPNotRead ()) ||
(ev_id == "nis" && Users::NISNotRead ()))
{
UI::OpenDialog (`opt(`decorated ),
// wait popup
`Label(_("Reading sets of users and groups. Please wait...")));
popup = true;
}
if (Users::ChangeCurrentGroups ((string) ev_id))
{
if (popup)
{
UI::CloseDialog ();
popup = false;
}
UsersCache::SetCustomizedGroupsView (ev_id == "custom");
SummaryTableInit ("table");
InitFilterLine (widget_id);
InitTabUsersGroups ("");
}
if (popup) UI::CloseDialog ();
return nil;
}
if (ev_id == `customize)
{
if (CustomizePopup (current_summary) &&
UsersCache::CustomizedUsersView ())
{
SummaryTableInit ("table");
}
InitFilterLine (widget_id);
InitTabUsersGroups ("");
return nil;
}
if (! is (ev_id, symbol))
{
y2error ("strange ev_id value: %1", ev_id);
return nil;
}
return (symbol) ev_id;
}
/**
* helper function to get information about authentication from
* appropriate module
* @param client
* @return
*/
define string get_module_data (string client) {
string ret = "";
boolean progress_orig = Progress::set (false);
if (!contains (installed_clients, client))
{
ret = Summary::NotConfigured();
}
else if (client == "ldap")
{
Ldap::Read();
ret = Ldap::ShortSummary();
}
else if (client == "nis")
{
WFM::CallFunction ("nis_auto", ["Read"]);
any a = WFM::CallFunction ("nis_auto", ["ShortSummary"]);
if (is (a,string))
ret = (string) a;
}
else if (client == "kerberos")
{
WFM::CallFunction ("kerberos-client_auto", ["Read"]);
any a = WFM::CallFunction ("kerberos-client_auto",["ShortSummary"]);
if (is (a,string))
ret = (string) a;
}
else if (client == "samba")
{
WFM::CallFunction ("samba-client_auto", ["Read"]);
any a = WFM::CallFunction ("samba-client_auto", ["ShortSummary"]);
if (is (a,string))
ret = (string) a;
}
Progress::set (progress_orig);
return ret;
}
/**
* Reloads the configuration for given client and creates updated
* summary widget contents
* returns the summary value for richtext
*/
define string reload_config (list<string> clients) {
string summary = "";
if (clients == nil || clients == [])
clients = configurable_clients;
foreach (string client, clients, {
summary = Summary::AddHeader (summary, sformat (
"<font color=\"#8BC460\"><a href=\"%1\">%2</a></font>",
client, client_label[client]:client));
summary = Summary::AddLine (summary, get_module_data (client));
});
return summary;
}
/**
* Init the widgets in Authentication tab
*/
define void InitAuthData (string key) {
list mb = [];
map to_string = $[
// menubutton label
"nis" : _("&NIS"),
// menubutton label
"nisplus" : _("N&IS+"),
// menubutton label
"ldap" : _("&LDAP"),
// menubutton label
"kerberos" : _("&Kerberos"),
// menubutton label
"samba" : _("&Samba"),
];
// check availability of authentication packages,
// update the RichText summary and menubutton labels accordingly
foreach (string client, configurable_clients, {
string package = sformat ("yast2-%1-client", client);
term client_item = `item (`id(client), to_string[client]:client);
if (Package::Installed (package))
{
installed_clients = add (installed_clients, client);
}
mb = add (mb, client_item);
UI::ChangeWidget (`id ("auth_summary"), `Value,
(string) UI::QueryWidget (`id ("auth_summary"),`Value) +
reload_config ([client])
);
});
if (size (mb) > 0)
{
UI::ReplaceWidget (`id (`rpbutton),
// menu button label
`MenuButton(`opt(`key_F4), _("&Configure..."), mb)
);
}
}
/**
* Handler for actions in Authentication tab
*/
symbol HandleAuthData (string key, map event) {
if (event["EventType"]:"" != "MenuEvent") return nil;
string button = event["ID"]:"";
if (!contains (configurable_clients, button)) return nil;
if (!contains (installed_clients, (string) button))
{
string package = sformat ("yast2-%1-client", button);
if (check_available)
{
boolean avai = Package::Available (package);
if (avai == nil)
{
// package manager is probably not accessible -> no more checks
check_available = false;
}
if (avai != true)
{
// error popup, %1 is package name
Popup::Error (sformat (_("Package %1 is not available for installation."),
package));
configurable_clients = filter (string p,configurable_clients,
``(p != button));
UI::ChangeWidget (`id ("auth_summary"), `Value, reload_config ([]));
return nil;
}
}
if (Package::InstallAllMsg ([package],
// popup label (%1 is package to install)
sformat (_("Package %1 is not installed.
Install it now?
"), package)))
{
installed_clients = add (installed_clients, (string) button);
}
else
{
return nil;
}
}
list param = installation () ? [ "from_users" ] : [];
if (WFM::CallFunction ((string)call_module[button]:button, param) == `next)
{
UI::ChangeWidget (`id ("auth_summary"), `Value, reload_config ([]));
}
return nil;
}
/**
* Actions done when Authentication tab is left
*/
define void StoreAuthData (string key, map event) {
boolean was_nis_available = Users::NISAvailable ();
boolean was_ldap_available = Users::LDAPAvailable ();
Users::ReadSourcesSettings();
// enabling NIS/LDAP could add + lines (they are not in current cache that
// would be saved after user modifications):
if ((!was_nis_available && Users::NISAvailable ()) ||
(!was_ldap_available && Users::LDAPAvailable()))
{
y2milestone ("ldap or nis enabled now");
Users::AddPlusPasswd ("+::::::");
Users::AddPlusGroup ("+:::");
Users::AddPlusShadow ("+");
}
}
map tabs_description = $[
"users" : $[
// tab header
"header" : _("&Users"),
"contents" : `HBox (`HSpacing (0.5), `VBox (
"filter_line",
"tab_switch_users",
"table"
), `HSpacing (0.5)),
"widget_names" : [
"tab_switch_users",
"filter_line",
"table",
],
],
"groups" : $[
// tab header
"header" : _("&Groups"),
"contents" : `HBox (`HSpacing (0.5), `VBox (
"filter_line",
"tab_switch_groups",
"table"
), `HSpacing (0.5)),
"widget_names" : [
"tab_switch_groups",
"filter_line",
"table",
],
],
"defaults" : $[
// tab header
"header" : _("De&faults for New Users"),
"contents" : `HBox (`HSpacing (2), `VBox (
`VStretch (),
`VSpacing(0.2),
"defaults_global",
"defaultgroup",
"groups",
"shell",
`HBox (
"home",
`VBox (`Label (""), "browse_home")
),
`HBox(
"skel",
`VBox (`Label (""), "browse_skel")
),
"umask",
"expire",
"inactive",
`VSpacing (0.2),
`VStretch ()
), `HSpacing (2)),
"widget_names" : [
"defaults_global",
"defaultgroup", "groups", "shell", "home", "browse_home",
"skel", "browse_skel", "umask", "expire", "inactive",
],
],
"authentication" : $[
// tab header
"header" : _("&Authentication Settings"),
"contents" : `HBox (`HSpacing (), `VBox(
`VSpacing(0.5),
"auth_global",
`VSpacing (0.5)
), `HSpacing ()),
"widget_names" : [
"auth_global",
],
]
];
map <string, map <string, any> > widgets = $[
// widgets for "users" and "groups" tabs ---------------------------------
"tab_switch_users" : $[
"widget" : `empty,
"init" : InitTabUsersGroups,
"help" : UsersDialogHelp (),
],
"tab_switch_groups" : $[
"widget" : `empty,
"init" : InitTabUsersGroups,
"help" : GroupsDialogHelp (),
],
"filter_line" : $[
"widget" : `custom,
"custom_widget" : `ReplacePoint (`id(`rpfilter), `HBox (
`Left (`Label (`id(`current_filter), "")),
`Right (`MenuButton (`id(`sets), `opt(`key_F2, `disabled),
_("&Set Filter"), []))
)),
"init" : InitFilterLine,
"handle" : HandleFilterLine,
"handle_events" : [
// these are for user/group types
"local", "system", "ldap", "nis", "custom",
`customize,
],
"no_help" : true
],
"table" : $[
"widget" : `custom,
"custom_widget" : `VBox (
`ReplacePoint (`id(`rptable), `Table (`id("table"), `header(""))),
`HBox (
`PushButton(`id(`new),`opt(`key_F3), Label::AddButton ()),
`PushButton(`id(`edit), `opt(`key_F4), Label::EditButton ()),
`PushButton(`id(`delete), `opt(`key_F5),Label::DeleteButton()),
`HStretch(),
`ReplacePoint (`id (`rpexpert),
// Menu Buton label
`MenuButton (`id(`expertlist), _("E&xpert Options"), [])
)
),
`VSpacing (0.2)
),
"init" : SummaryTableInit,
"handle" : HandleSummaryTable,
"handle_events" : [
"table", `new, `edit, `delete, `next, `enc, `autologinconf, `save,
`ldapfilter, `ldapconf,
],
"no_help" : true
],
// widgets for user defaults --------------------------------------------
"defaults_global" : $[
"widget" : `empty,
"init" : InitDefaults,
"store" : StoreDefaults,
"help" : DefaultsDialogHelp (),
],
"defaultgroup" : $[
"widget" : `combobox,
"opt" : [ `hstretch ],
// combobox label
"label" : _("D&efault Group"),
"no_help" : true,
],
"shell" : $[
"widget" : `combobox,
"opt" : [ `hstretch, `editable ],
// combobox label
"label" : _("Default &Login Shell"),
"no_help" : true,
"validate_type" : `function,
"validate_function" : ValidateShell,
],
"groups" : $[
"widget" : `textentry,
// text entry
"label" : _("Se&condary Groups"),
"no_help" : true,
"validate_type" : `function,
"validate_function" : ValidateGroupList,
],
"home" : $[
"widget" : `textentry,
// text entry
"label" : _("Path Prefix for &Home Directory"),
"no_help" : true,
"validate_type" : `function,
"validate_function" : ValidateHomePrefix,
],
"browse_home" : $[
"widget" : `push_button,
// push button label
"label" : _("&Browse..."),
"opt" : [ `key_F6 ],
"handle" : HandleBrowseDirectory,
"no_help" : true,
],
"skel" : $[
"widget" : `textentry,
// text entry
"label" : _("&Skeleton for Home Directory"),
"no_help" : true,
"validate_type" : `function,
"validate_function" : ValidateSkeleton,
],
"browse_skel" : $[
"widget" : `push_button,
// push button label
"label" : _("Bro&wse..."),
"opt" : [ `key_F7 ],
"handle" : HandleBrowseDirectory,
"no_help" : true,
],
"expire" : $[
"widget" : `textentry,
// text entry
"label" : _("Default E&xpiration Date"),
"no_help" : true,
"validate_type" : `function,
"validate_function" : ValidateExpire,
],
"umask" : $[
"widget" : `textentry,
"valid_chars" : "01234567",
// text entry
"label" : _("&Umask for Home Directory"),
"no_help" : true,
],
"inactive" : $[
"widget" : `intfield,
"opt" : [ `hstretch ],
// intfield
"label" : _("Days &after Password Expiration Login Is Usable"),
"minimum" : -1,
"no_help" : true,
],
// widgets for authentication settings tab ------------------------------
"auth_global" : $[
"widget" : `custom,
"help" : AuthentizationDialogHelp (),
"init" : InitAuthData,
"store" : StoreAuthData,
"handle" : HandleAuthData,
"custom_widget" : `VBox (
`RichText (`id ("auth_summary"), ""),
`VSpacing (0.5),
`ReplacePoint (`id (`rpbutton),
// menu button label
`MenuButton(`opt(`key_F4), _("&Configure..."), [])
)
),
"handle_events" : [
"ldap", "nis", "kerberos", "samba",
],
],
];
}//EOF
ACC SHELL 2018