#!/usr/bin/perl # Batch useradd written by the request of at least three different people # in sun-managers list. # Each had a slightly different request; I think this will accomodate all # of them. # Feel free to share this with everyone. # # scottvr@netcomi.com, 1998 # Disclaimer: This was written on a Solaris 2.5.1 box. It may not work on # yours though it has also worked for me on a Slackware Linux 3.4 box # with shadow and a SunOS 4.1.4 box. On the SunOS box, I had to modify # the path to the shadow file and take three of the ':' chars off of # $expiry; your results may vary. # Be smart, make backups before using. # Be smarter, read it and make sure you understand what it does # before you run it! # Be even smarter, don't set your users passwords to their usernames. # This program tries to make that a *little* safer by forcing the user # to change their password at first login if their password is their # username; still its not a good idea. Oh yeah, it worked when I ran it. :P # Usage: # create a text file (named in $newuserfile) containing the # usernames, the GECOS ("Real Name") field info, and an optional # password - seperated by ':' - one user per line. Then run this script. # # Example 1. # To create user 'user1' with realname 'User One' and password 'lus3r.1': # # user1:User One:lus3r.1 # # Example 2. # To create user 'fred' with realname 'fred' and password 'pass': # # fred::pass # # Example 3. # To add user 'barney', real name "Barney Rubble", password 'barney': # # barney:Barney Rubble # # Example 4. # To add user 'mrhanky', real name 'mrhanky', password 'mrhanky': # # mrhanky # # Also, "mrhanky::" or "mrhanky:" would both have also worked in the # above example. # # *note: if password is left off (set to username) it will be expired in # the shadow file so that the user is forced to change it at first logon # #Modified by Vincent Li vincent@brc.ubc.ca 2004-12-23, change crypt() to Crypt::PasswdMd5, worked on Fedora Core 3 #use strict; use Crypt::PasswdMD5 qw(unix_md5_crypt); @salt = ( '.', '/', 0 .. 9, 'A' .. 'Z', 'a' .. 'z' ); $uid=656; #first uid to give new users $gid=20; #gid to give newusers $shell='/sbin/nologin'; #shell we wish to give new users $home='/home'; #directory to put home directories in $passwd='/etc/passwd'; $shadow='/etc/shadow'; #in the format "username:Real Name" #one per line. $makedirs=0; #whether to make directories, etc or #simply create passwd/shadow entries #1 is passwd and dirs, 0 is just passwds #NB: the directories are made respecting #your umask. So check 'em ;) $skeldir='/etc/skel'; #directory containing newuser startup files die("You must be root for this to work!\n") unless ( -w $shadow ) ; $userfile=shift; print "$userfile\n"; open(USERLIST,"$userfile") or die("error reading $userfile\n"); @newusers=; close(USERLIST); open(PASSWD,"$passwd") or die("error reading $passwd"); @passwd=; close(PASSWD); open(SHADOW,"$shadow") or die("error reading $shadow"); @shadow=; close(SHADOW); foreach(@passwd) { ($user,$rest)=/^(\w+):(.*)$/; $users{$user}{passwd}="$rest"; push(@pusers,$user); } foreach(@shadow) { ($user,$rest)=/^(\w+):(.*)$/; $users{$user}{shadow}="$rest"; undef $user; undef $rest; } open(SHADOW,'>' . "$shadow"); select SHADOW ; $|=1; select STDOUT; open(PASSWD,'>' . "$passwd"); select PASSWD ; $|=1; select STDOUT; foreach(@pusers) { chomp; print PASSWD "$_:$users{$_}{passwd}\n"; print SHADOW "$_:$users{$_}{shadow}\n"; } foreach(@newusers) { next if(/^$/); $expiry=':12765:0:99999:7:::'; chomp(($name,$gecos,$plain)=split(':',$_)); $gecos=$name unless $gecos; ($plain=$name,$expiry=':0:1:1::::') unless $plain; $newshadow = (unix_md5_crypt($plain, gensalt(8) ) . "$expiry"); print PASSWD "$name:x:$uid:$gid:$gecos:$home/$name:$shell\n"; print SHADOW "$name:$newshadow\n"; #print "$name:x:$uid:$gid:$gecos:$home/$name:$shell\n"; #print "$name:$newshadow\n"; if($makedirs) { mkdir("$home/$name",0755) unless( -d "$home/$name" ); opendir(SKEL,"/etc/skel"); foreach(readdir(SKEL)) { next if /^\.\.?$/; system 'cp', $_, "$home/$name"; chown($uid,$gid,"$home/$name/" . $_); } chown($uid,$gid,"$home/$name/"); } $uid++; undef $name,$uid,$gecos,$gid } close(PASSWD); close(SHADOW); # uses global @salt to construct salt string of requested length sub gensalt { $count = shift; for (1..$count) { $salt .= (@salt)[rand @salt]; } return $salt; }