Is it possible to import users by using CSV file? or something like a LDAP connection to import all users?
6 Answers
There's an app for that! The newusers tool which is part of the passwd package is designed to batch create users:
DESCRIPTION
The newusers command reads a file (or the standard input by default)
and uses this information to update a set of existing users or to
create new users. Each line is in the same format as the standard
password file (see passwd(5)) with the exceptions explained below:
You will need to create a file with this format:
username:passwd:UID:GID:full name,room number,work phone,home phone,other:directory:shell
Many of these can be ignored and the default values will be used. You only need to specify the username and password. For example:
tom:password1:::::
danny:password2:::::
If I save that as users.txt and run this command:
sudo newusers < users.txt
The users are created:
$ grep -E 'tom|danny' /etc/passwd
tom:x:1005:1006:::
danny:x:1006:1007:::
- 104,404
-
-
-
@A.B. in that case, you need to use a different tool. I can't figure out how to have a colon in a password for
newuser. Neither quoting, nor escaping seems to work :( – terdon Jun 08 '15 at 18:38 -
Are you sure it works? Last time I tried it failed as soon as there was more than one line in the file - see https://bugs.launchpad.net/ubuntu/+source/shadow/+bug/1266675. – guntbert Jun 08 '15 at 19:21
With a script you can. This needs a file with user and password commaseparated:
while IFS="," read -r user passwd ; do
echo "useradd -m -p $(mkpasswd "$passwd") $user"
done < /home/$USER/Downloads/users.txt
mkpasswdcan be installed withsudo apt-get install whois- Change the , to a ; if you need that.
Save this as users.sh and set permissions with chmod +x users.sh
If you then do
./users.sh > users_create.sh
You get a text file with all the commands so you can verify it and
chmod +x users.sh
./users_create.sh
will then create them.
Testing
Example file:
wdn,password123
wdn2,password345
saved as "users.txt" in "~/Downloads".
Execute script:
./users.sh
useradd -m -p acBNi2tbw9iaw wdn
useradd -m -p OHOzeMGqbcMso wdn2
and
./users.sh > users_create.sh
~/Downloads$ more users_create.sh
useradd -m -p Q1BVotdoA3ucI wdn
useradd -m -p siUX7mYTYw.3A wdn2
(password are encrypted).
After this all you need to do is execute is to make this executable with chmod +x users.sh and execute it with ./users_create.sh (I did not do that last bit so if not working please comment).
-
2
for users in $(cat file)is not the best way to loop in a file. Instead, just usewhile IFS="," read -r user passwd ; do ... ; done < file.$userand$passwdwill contain the 1st and 2nd columns, etc. – fedorqui Jun 08 '15 at 11:42 -
1
-
Yep, way better. I would also use
$()instead of backticks, since they are preferred. Also, it is always good practice to quote variables whenechoing – fedorqui Jun 08 '15 at 11:55 -
-
Here is an awk one-liner:
sudo awk -F',' '{ command="useradd -p $( mkpasswd "$2" ) "$1;print command; system(command) }' userlist.txt
Or for readability, here's the format:
sudo awk -F',' '{
command="useradd -p $(mkpasswd "$2 ")" $1;
print command;
system(command)
}' userlist.txt
Explanation:
awk's system function allows running shell commands while awk is processing entries from text file. We create a variable "command" that is just text of the command we want to run. Using comma as field separator -F',' , we take field #2 and #1 and place them to match syntax of the useradd command. Once the text of the command is assembled, system(command) executes useradd -p $(mkpasswd password) username , for each line of the text. print command part is optional, merely for debugging and verifying that all usernames have been processed
Addition:
The oneliner can be turned into an awk script like so:
#!/usr/bin/awk -f
BEGIN {FS=",";}
{
command="useradd -p $(mkpasswd "$2") " $1;
print command;
system( command )
}
Now make sure the script has executable permissions with sudo chmod +x script-name.awk and run it with any input file like so sudo ./awkscript.sh userlist.txt if it is in your current working directory, or you can call that script anywhere by placing it into one of the $PATH directories
Possible , in the password
To take into account possibility of having comma in password, I suggest you use sub() function. Sub function changes first instance of a character or word in each line. In other words, if we have an entry such as testuser,foo,bar, where foo,bar is password, and we change first entry to space, we can use awk normally , without telling it to use -F',' flag. Awk will translate each entry to testuser foo,bar, and treat testuser as $1 and foo,bar as $2. To put this into code:
sudo awk '{ sub(","," ");command="useradd -p $( mkpasswd "$2" ) "$1;print command; system(command) }' userlist.txt
- 92,275
- 107,880
Here is a python solution:
#!/usr/bin/env python2
import subprocess, crypt
with open('/path/to/file.csv') as f:
for line in f:
i = line.find(',')
name = line[:i]
password = line.rstrip()[i+1:]
encpt_passwd = crypt.crypt(password, '2b')
command = 'useradd -m -p {0} {1}'.format(encpt_passwd, name).split()
subprocess.call(command)
This will handle passwords having commas.
line.find(',')will find the lowest index of,in each line of the fileline[:i]will take the slice of the line containg the usernameline.rstrip()[i+1:]will contain the passwordcryptmodule generates encrypted password from input of the formcrypt.crypt(password, salt).encpt_passwdwill contain the encrypted password. Incrypt.crypt(password, '2b'),passwordis the saved plain password and2bis the salt.subprocess.call(command)will simply run the command to generate users
- 94,145
I have a shorter awk version (@Serg =)):
First install whois, we need the command mkpasswd
sudo apt-get install whois
Than you can use this oneliner:
awk -F',' '{print "Create user: "$1; system("sudo useradd -p $(mkpasswd "$2") "$1)}' users
or without any output:
awk -F',' '{system("sudo useradd -p $(mkpasswd "$2") "$1)}' users
Content of users:
foo,foopasswd
bar,password
foobar,foobar
The user name is in the first column, the unencrypted password in the 2nd column.
In fairness, I mention a problem here. Passwords can not include a comma.
- 92,275
My AWK version has a problem with , in the password. Here is my perl version:
#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;
my $file = $ARGV[0];
open my $fh, "<", $file or die "$file: $!";
my $csv = Text::CSV->new ({
binary => 1, # Allow special character. Always set this
auto_diag => 1, # Report irregularities immediately
sep_char => ','
});
while (my $row = $csv->getline ($fh)) {
print "User: ".$row->[0]."\n";
print "Password: ".$row->[1]."\n";
my $hashed = crypt($row->[1], "salt");
my $cmd = 'useradd -p '.$hashed.' '.$row->[0]."\n";
system($cmd);
}
close $fh;
Example:
CSV file users.csv:
foo,"foopasswd"
bar,"password"
foobar,"""foo,bar"
Start the script
% sudo add_users users.csv
User: foo
Password: foopasswd
useradd -p sajllSNct/Wx2 foo
User: bar
Password: password
useradd -p sa3tHJ3/KuYvI bar
User: foobar
Password: "foo,bar
useradd -p saBWMpscG9WvA foobar
- 92,275
adduseroruseraddfor each user. For LDAP you need to configure PAM. I recommend to focus your question to one of these two solutions because they are so completely different – Daniel Alder Jun 08 '15 at 09:27