pfSsh.php playback script to change username
-
I have this working pfSsh.php playback script that takes a current/existing username and a new username as arguments and changes the existing username to the new username.
require_once("config.inc"); require_once("auth.inc"); require_once("functions.inc"); global $argv, $userindex; $userindex = index_users(); $args = array_slice($argv, 3); if (empty($args[0]) || empty($args[1])) { exit(-1); } else { $oldusername = $args[0]; $newusername = $args[1]; } $oldusername = trim($oldusername); $newusername = trim($newusername); $user_item_config = getUserEntry($oldusername); $user = &$user_item_config['item']; if ($user == NULL) { exit(-1); } if ($oldusername !== $newusername) { config_set_path("/system/user/" . $userindex[$oldusername] . "/name", $newusername); write_config(sprintf(gettext("Username changed for user '%s' from console."), $oldusername)); exit(0); } else { exit(-1); }
I started with the "built-in" changepassword script and tweaked it for my purposes. While my script to change usernames works, it doesn't change the user's home directory to the new username, and at first if I do something like pw usershow -n oldusername, I still see an entry for the old user. If I reboot, pw usershow -n oldusername returns 'no such user', but /home/oldusername still exists. /home/newusername exists as well. I'm wondering if there is a preferred/standard/idiomatic approach? I first tried the playback script below, thinking local_user_set() (found in /etc/inc/auth.inc) would handle a username change more thoroughly/properly, but had no success.
require_once("config.inc"); require_once("auth.inc"); require_once("functions.inc"); global $argv, $userindex; $userindex = index_users(); $args = array_slice($argv, 3); if (empty($args[0]) || empty($args[1])) { exit(-1); } else { $oldusername = $args[0]; $newusername = $args[1]; } $oldusername = trim($oldusername); $newusername = trim($newusername); $user_item_config = getUserEntry($oldusername); $user = &$user_item_config['item']; if ($user == NULL) { exit(-1); } if ($oldusername !== $newusername) { $user['name'] = $newusername; local_user_set($user); write_config(sprintf(gettext("Username changed for user '%s' from console."), $oldusername)); exit(0); } else { exit(-1); }
In this part of local_user_set(), I did confirm it uses the success branch (useradd), when I attempt to change a username:
/* determine add or mod */ if (($userattrs[0] != $user['name']) || (!strncmp($pwread, "pw:", 3))) { $user_op = "useradd -m -k " . escapeshellarg($skel_dir) . " -o"; } else { $user_op = "usermod"; }
Not what I'm trying to achieve.
I also tried:mv /home/oldusername /home/newusername pw usermod -n oldusername -d /home/newusername -l newusername
But this seems to leave the system in an inconsistent state.
pw usershow -n oldusername
still shows an entry for the old/original username. Interestingly,
getent passwd
does not.