ACC SHELL
/**
* File: include/users/cmdline.ycp
* Package: Configuration of users and groups
* Summary: Command line interface functions.
* Authors: Jiri Suchomel <jsuchome@suse.cz>
*
* $Id: cmdline.ycp 52149 2008-10-13 14:56:39Z jsuchome $
*
* All command line interface functions.
*/
{
textdomain "users";
import "CommandLine";
import "Ldap";
import "Users";
import "UsersCache";
import "UsersLDAP";
import "UsersSimple";
import "Report";
// --------------------------------------------------------------------------
// --------------------------------- helper functions -----------------------
/**
* set LDAP admin password and read LDAP users and groups
*/
define boolean bind_and_read_LDAP (map<string,any> options) {
string pw = options["ldap_password"]:"";
if (Users::LDAPAvailable() && Users::LDAPNotRead())
{
if (Ldap::bind_pass == nil)
{
if (pw == "" && !haskey (options, "batchmode"))
{
// password entering label
pw = CommandLine::PasswordInput (_("LDAP Server Password:"));
}
Ldap::SetBindPassword (pw);
// TODO check bind...
}
string error = UsersLDAP::ReadSettings ();
if (error != "")
{
CommandLine::Print (error);
return false;
}
error = Users::ReadLDAPSet ("Users");
if (error != "")
{
CommandLine::Print (error);
return false;
}
}
return true;
}
define map<string,any> convert_keys (map<string,any> input) ``{
map<string,any> ret = $[];
map keys = $[
"username" : "uid",
"password" : "userPassword",
"home" : "homeDirectory",
"shell" : "loginShell",
"fullname" : "cn",
"gid" : "gidNumber",
"uid" : "uidNumber",
"no_home" : "create_home",
"groupname" : "cn",
"new_username" : "uid",
"new_groupname" : "cn",
"new_uid" : "uidNumber",
"new_gid" : "gidNumber",
UsersLDAP::GetMemberAttribute (): "userlist",
];
foreach (string key, any value, input, ``{
string new_key = keys[key]:key;
if (new_key == "create_home")
value = false;
if (new_key == "gidNumber" && value != "" &&
(haskey (input,"username") || haskey (input,"uid")))
{
// check group existence!
if (!UsersCache::GIDExists (tointeger ((string)value)))
return;
}
if (new_key == "grouplist" && is (value, string))
{
value = listmap (string g, splitstring ((string)value,","),
``($[g : 1]));
}
if (new_key == "userlist" && is (value, string))
{
string sep = ",";
if (issubstring ((string)value,"="))//for DN
sep = ":";
value = listmap (
string u, splitstring ((string)value,sep), ``($[u:1]));
}
if (new_key == "ldap_password")
return;
if ((key == "username" && haskey (input, "new_username")) ||
(key == "uid" && haskey (input, "new_uid")) ||
(key == "groupname" && haskey (input, "new_groupname")) ||
(key == "gid" && haskey (input, "new_gid")))
return;
ret [ new_key ] = value;
});
return ret;
}
// --------------------------------------------------------------------------
// --------------------------------- cmd-line handlers for users ------------
/**
* List users
* @return boolean false
*/
define boolean UsersListHandler (map<string,any> options ) ``{
list<string> sets = [];
list<string> attributes = [];
map<string,any> amap = $[];
foreach (string key, any val, options, ``{
if (contains (["local","system","ldap","nis"], key))
sets = add (sets, key);
else
// attributes = (list<string>) union (attributes, [type]);
amap [key] = val;
});
if (sets == [])
sets = ["local"];
attributes = maplist (string k,any val, convert_keys (amap), ``(k));
if (!contains (attributes, "uid"))
attributes = prepend (attributes, "uid");
foreach (string type, sets, ``{
if (type == "nis" && Users::NISAvailable () && Users::NISNotRead ())
{
Users::ReadNewSet ("nis");
}
if (type == "ldap" && Users::LDAPAvailable () && Users::LDAPNotRead ())
{
Ldap::SetAnonymous (true);
Users::ReadNewSet ("ldap");
}
foreach (string uname, map user, (map<string,map>) Users::GetUsers ("uid",type), ``{
string out = "";
// FIXME when using convert_keys, the order is broken...
foreach (string attr, attributes, ``{
if (haskey (user,attr))
{
if (is (user[attr]:nil, string))
out = out + user[attr]:"" + " ";
if (is (user[attr]:nil, map))
out = out + mergestring (
maplist (string k, any v,user[attr]:$[],``(k)),",")
+ " ";
}
});
CommandLine::Print (out);
});
});
return false; // do not call Write...
}
/**
* Show one user information
* @return boolean false
*/
define boolean UserShowHandler (map options ) ``{
map<string,any> user = $[];
integer uid = tointeger (options ["uidNumber"]:options["uid"]:"-1");
string username = options ["username"]:"";
string type = options ["type"]:"local";
if (type == "nis" && Users::NISAvailable () && Users::NISNotRead ())
{
Users::ReadNewSet ("nis");
}
if (type == "ldap" && Users::LDAPAvailable () && Users::LDAPNotRead ())
{
Ldap::SetAnonymous (true);
Users::ReadNewSet ("ldap");
}
if (uid != -1 && uid != nil)
{
user = Users::GetUser (uid, "");
}
else if (username != "")
{
user = Users::GetUserByName (username, "");
}
if (user == $[])
{
// error message
CommandLine::Print (_("There is no such user."));
return false;
}
string out = "";
map keys = $[
// label shown at command line (user attribute)
"cn" : _("Full Name:"),
// label shown at command line (user attribute)
"uid" : _("Login Name:"),
// label shown at command line (user attribute)
"homeDirectory" : _("Home Directory:"),
// label shown at command line (user attribute)
"loginShell" : _("Login Shell:"),
// label shown at command line (user attribute)
"uidNumber" : _("UID:"),
// label shown at command line (user attribute)
"groupname" : _("Default Group:"),
// label shown at command line (user attribute)
"grouplist" : _("List of Groups:"),
];
foreach (string key, any value, user, ``{
key = keys[key]:"";
if (key == "") return;
string svalue = sformat ("%1", value);
if (is (value, map))
{
svalue = mergestring ((list<string>)
maplist (string k, any v, (map<string,any>) value, ``(k)), ",");
}
CommandLine::Print (sformat ("%1\n\t%2", key, svalue));
});
return false; // do not call Write...
}
/**
* Add user
* @return boolean false
*/
define boolean UserAddHandler (map <string, any> options ) ``{
if (options["username"]:"" == "")
{
// error message
CommandLine::Print (_("Enter a user name."));
return false;
}
map <string, any> user = convert_keys (options);
string type = user["type"]:"local";
if (type == "ldap")
{
if (!bind_and_read_LDAP (options))
return false;
if (!haskey (user,"sn"))
user["sn"] = user["uid"]:"";
}
Users::ResetCurrentUser ();
if (!haskey(user,"userPassword") && !haskey (user, "batchmode"))
{
string pw = "";
integer i = 0;
while (true)
{
// question on command line
pw = CommandLine::PasswordInput (_("Password for New User:"));
string p2 = CommandLine::PasswordInput (
// question on command line
_("Confirm the password:"));
if (pw != p2)
{
if (i < 2)
{
// error message
CommandLine::Print(_("Passwords do not match. Try again."));
i = i + 1;
}
else
{
// error message
CommandLine::Print(_("Passwords do not match. Exiting."));
return false;
}
}
else break;
}
user["userPassword"] = pw;
}
string error = UsersSimple::CheckPassword (user["userPassword"]:"", type);
if (error != "")
{
CommandLine::Print (error);
return false;
}
error = Users::AddUser (user);
if (error != "")
{
CommandLine::Print (error);
return false;
}
if (user["type"]:"local" == "ldap")
{
Users::SubstituteUserValues ();
}
error = Users::CheckUser ($[]);
if (error != "")
{
CommandLine::Print (error);
return false;
}
return Users::CommitUser ();
}
/**
* Delete user
* @return boolean false
*/
define boolean UserDeleteHandler (map <string, any>options ) ``{
integer uid = tointeger (options ["uidNumber"]:options["uid"]:"-1");
string username = options ["username"]:"";
boolean delete_home = haskey (options, "delete_home");
string type = options["type"]:"local";
if (type == "ldap")
{
if (!bind_and_read_LDAP (options))
return false;
}
if (uid != -1 && uid != nil)
{
Users::SelectUser (uid);
}
else if (username != "")
{
Users::SelectUserByName (username);
map u = Users::GetCurrentUser();
if (is (u["uidNumber"]:nil, integer))
uid = u["uidNumber"]:-1;
else if (is (u["uidNumber"]:nil, string))
uid = tointeger (u["uidNumber"]:"-1");
}
if (Users::GetCurrentUser () == $[])
{
// error message
CommandLine::Print (_("There is no such user."));
return false;
}
// if the user has log on system
map out = (map)SCR::Execute (.target.bash_output,
sformat ("ps --no-headers -u %1", uid));
if (size (out["stdout"]:"") != 0)
{
// error popup
Report::Error(_("You can not delete this user, because the user is present.
Please log off the user first."));
return false;
}
return Users::DeleteUser (delete_home) && Users::CommitUser ();
}
/**
* Edit user
* @return boolean false
*/
define boolean UserEditHandler (map<string,any> options) {
integer uid = tointeger (options ["uidNumber"]:options["uid"]:"-1");
string username = options ["username"]:"";
string type = options["type"]:"local";
if (type == "ldap")
{
if (!bind_and_read_LDAP (options))
return false;
}
if (uid != -1 && uid != nil)
{
Users::SelectUser (uid);
}
else if (username != "")
{
Users::SelectUserByName (username);
}
map user = Users::GetCurrentUser ();
if (user == $[])
{
// error message
CommandLine::Print (_("There is no such user."));
return false;
}
map changes = convert_keys (options);
if (type == "ldap" && !haskey (changes,"dn"))
{
changes["dn"] = user["dn"]:"";
// for username changes...
}
string error = Users::EditUser ((map<string,any>)changes);
if (error != "")
{
CommandLine::Print (error);
return false;
}
error = Users::CheckUser ($[]);
if (error != "")
{
CommandLine::Print (error);
return false;
}
return Users::CommitUser ();
}
// --------------------------------------------------------------------------
// --------------------------------- cmd-line handlers for groups -----------
/**
* List groups
* @return boolean false
*/
define boolean GroupsListHandler (map<string,string> options ) ``{
list<string> sets = [];
list<string> attributes = [];
map<string,any> amap = $[];
foreach (string key, any val, options, ``{
if (contains (["local","system","ldap","nis"], key))
sets = add (sets, key);
else
amap [key] = val;
});
if (sets == [])
sets = ["local"];
attributes = maplist (string k,any val, convert_keys (amap), ``(k));
if (!contains (attributes, "cn"))
attributes = prepend (attributes, "cn");
if (contains (attributes, "userlist"))
attributes = add (attributes, UsersLDAP::GetMemberAttribute ());
foreach (string type, sets, {
if (type == "nis" && Users::NISAvailable () && Users::NISNotRead ())
{
Users::ReadNewSet ("nis");
}
if (type == "ldap" && Users::LDAPAvailable () && Users::LDAPNotRead ())
{
Ldap::SetAnonymous (true);
Users::ReadNewSet ("ldap");
}
foreach (string name, map group, (map<string,map>) Users::GetGroups ("cn",type), {
string out = "";
foreach (string attr, attributes, ``{
if (haskey (group,attr))
{
if (is (group[attr]:nil, string))
out = out + group[attr]:"" + " ";
if (is (group[attr]:nil, map))
out = out + mergestring (
maplist (string k, any v,group[attr]:$[],``(k)),",")
+ " ";
}
});
CommandLine::Print (out);
});
});
return false; // do not call Write...
}
/**
* Show one group information
* @return boolean false
*/
define boolean GroupShowHandler (map options ) ``{
map<string,any> group = $[];
integer gid = tointeger (options ["gidNumber"]:options["gid"]:"-1");
string groupname = options ["groupname"]:"";
string type = options ["type"]:"local";
if (type == "nis" && Users::NISAvailable () && Users::NISNotRead ())
{
Users::ReadNewSet ("nis");
}
if (type == "ldap" && Users::LDAPAvailable () && Users::LDAPNotRead ())
{
Ldap::SetAnonymous (true);
Users::ReadNewSet ("ldap");
}
if (gid != -1 && gid != nil)
{
group = Users::GetGroup (gid, "");
}
else if (groupname != "")
{
group = Users::GetGroupByName (groupname, "");
}
if (group == $[])
{
// error message
CommandLine::Print (_("There is no such group."));
return false;
}
string out = "";
map keys = $[
// label shown at command line (user attribute)
"cn" : _("Group Name:"),
// label shown at command line (user attribute)
"gidNumber" : _("GID:"),
// label shown at command line (user attribute)
"userlist" : _("List of Members:"),
// label shown at command line (user attribute)
UsersLDAP::GetMemberAttribute (): _("List of Members:"),
];
foreach (string key, any value, group, ``{
key = keys[key]:"";
if (key == "") return;
string svalue = sformat ("%1", value);
if (is (value, map))
{
svalue = mergestring ((list<string>)
maplist (string k, any v, (map<string,any>) value, ``(k)), ",");
}
CommandLine::Print (sformat ("%1\n\t%2", key, svalue));
});
return false; // do not call Write...
}
/**
* Delete group
* @return boolean false
*/
define boolean GroupDeleteHandler (map<string,any> options ) {
integer gid = tointeger (options ["gidNumber"]:options["gid"]:"-1");
string groupname = options ["cn"]:options["groupname"]:"";
string type = options["type"]:"local";
if (type == "ldap")
{
if (!bind_and_read_LDAP (options))
return false;
}
if (gid != -1 && gid != nil)
{
Users::SelectGroup (gid);
}
else if (groupname != "")
{
Users::SelectGroupByName (groupname);
}
if (Users::GetCurrentGroup () == $[])
{
// error message
CommandLine::Print (_("There is no such group."));
return false;
}
return Users::DeleteGroup () && Users::CommitGroup ();
}
/**
* Add group
* @return boolean false
*/
define boolean GroupAddHandler (map <string, any> options ) {
if (options["groupname"]:"" == "")
{
// error message
CommandLine::Print (_("Enter a group name."));
return false;
}
map <string, any> group = convert_keys (options);
string type = group["type"]:"local";
if (type == "ldap")
{
if (!bind_and_read_LDAP (options))
return false;
}
string member_attr = (type == "ldap") ? UsersLDAP::GetMemberAttribute () :
"userlist";
if (haskey (group, "userlist"))
{
if (type == "ldap")
{
group [member_attr] = group["userlist"]:$[];
group = remove (group, "userlist");
}
}
else
{
group [member_attr] = $[];
}
Users::ResetCurrentGroup ();
string error = Users::AddGroup (group);
if (error != "")
{
CommandLine::Print (error);
return false;
}
if (group["type"]:"local" == "ldap")
{
Users::SubstituteGroupValues ();
}
error = Users::CheckGroup ($[]);
if (error != "")
{
CommandLine::Print (error);
return false;
}
return Users::CommitGroup ();
}
/**
* Edit group
* @return boolean false
*/
define boolean GroupEditHandler (map<string,any> options) {
integer gid = tointeger (options ["gidNumber"]:options["gid"]:"-1");
string groupname = options ["cn"]:options["groupname"]:"";
string type = options["type"]:"local";
if (type == "ldap")
{
if (!bind_and_read_LDAP (options))
return false;
}
if (gid != -1 && gid != nil)
{
Users::SelectGroup (gid);
}
else if (groupname != "")
{
Users::SelectGroupByName (groupname);
}
map group = Users::GetCurrentGroup ();
if (group == $[])
{
// error message
CommandLine::Print (_("There is no such group."));
return false;
}
map changes = convert_keys (options);
if (type == "ldap" && !haskey (changes,"dn"))
{
changes["dn"] = group["dn"]:"";
// for groupname changes...
}
if (type == "ldap" && haskey (changes, "userlist"))
{
changes [UsersLDAP::GetMemberAttribute ()] = changes["userlist"]:$[];
changes = remove (changes, "userlist");
}
string error = Users::EditGroup ((map<string,any>)changes);
if (error != "")
{
CommandLine::Print (error);
return false;
}
error = Users::CheckGroup ($[]);
if (error != "")
{
CommandLine::Print (error);
return false;
}
return Users::CommitGroup ();
}
// --------------------------------------------------------------------------
// --------------------------------- common cmd-line handlers ---------------
define boolean UsersRead () ``{
Users::SetGUI (false);
return Users::Read () == "";
}
define boolean UsersWrite () ``{
Users::SetGUI (false);
string error = Users::Write ();
if (error != "")
{
CommandLine::Print (error);
return false;
}
return true;
}
define boolean UsersGUI () {
return (UsersSequence (Users::GetStartDialog()) == `next);
}
} //EOF
ACC SHELL 2018