mldvx4 has asked for the wisdom of the Perl Monks concerning the following question:

The following changes the account name just fine except that it also produces an error "user name ... already exists ... at line ...". Just to be clear, the old name changes to the new name in /etc/passwd when the script is run, but it produces an error while doing so. What is the correct way to use Linux::usermod so that no error is produce when changing the account name?

sub rename_account { my ($name,$nname) = (@_); my $account = Linux::usermod->new($name); $account->set('name'=>$nname); }

Perhaps it is a misunderstanding in how to use Linux::usermod. Looking at the manual page, that looks like the correct usage. So perhaps I have read and interpreted it incorrectly.

Edit: The problem seems related to /etc/shadow which seems like it is not updated. So if one changes back and forth between the same two names, the first change goes through but leaves the old name in /etc/shadow so the second attempt fails because the old name is still their. I think...

Replies are listed 'Best First'.
Re: Linux::usermod - user name ... already exists
by thanos1983 (Parson) on Mar 19, 2019 at 12:09 UTC

    Hello mldvx4,

    An alternative solution would be to change the username through the usermod and also after the /home dir if exists?

    Sample of code:

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my $nname = "monk"; my $name = "testuser"; sub rename_account { my ( $name , $nname ) = ( @_ ); my $username = `usermod -l $nname $name`; my $dirusername = `usermod -d /home/$nname -m $nname`; chomp(my @dir = `ls -la /home`); print Dumper \@dir; } # rename_account("monk", "testuser"); rename_account("testuser", "monk"); __END__ $ sudo perl sample.pl $VAR1 = [ 'total 16', 'drwxr-xr-x 4 root root 4096 Mar 19 12:57 .', 'drwxr-xr-x 24 root root 4096 Mar 7 15:04 ..', 'drwxr-xr-x 2 monk testuser 4096 Mar 19 12:51 monk', ];

    The script will not produce any error if the user exists etc.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
      my $username = `usermod -l $nname $name`; my $dirusername = `usermod -d /home/$nname -m $nname`;

      I would recommend against this way of doing this because it allows for injection of arbitrary shell commands via $nname and $name, and it does not check for errors in the commands. See also.

        Hello haukex,

        I read your post so I guess something like that should be better :).

        Update: Adding minor conversion STDOUT to array for better data manipulation.

        Thank you for the information. BR / Thanos

        Seeking for Perl wisdom...on the process of learning...not there...yet!

      Yes, a shell script would be an option. It looks like the problem may be Linux::usermod not taking care of /etc/shadow properly. I'm doing some experiments to see if I can scope out the bug.

      It's part of a larger, more complex task where the script can change the name of the account and then update all the groups in which it is a member.

        Hello again mldvx4,

        I was thinking exactly like this. That your script will do something like that.

        Well an alternative solution would be to remove the user Linux::usermod->del(username); (I assume the module removes the user from all groups) and after that create a new user Linux::usermod->add(username, password, uid, gid, comment, home, shell); with the updated name. That could be a workaround (assuming there are no errors on this one as well). Not to forget you can assign the user to the desired groups

        @users = qw(user1 user2 user3); Linux::usermod->grpadd(groupname, gid, "@users")
        . But again this is just theory I have not tested it so I do not know if there is a bug in all these commands.

        Let us know at the end what solution you came up with. BR / Thanos

        Seeking for Perl wisdom...on the process of learning...not there...yet!