Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Nov 2001 11:10:37 +0300
From:      Odhiambo Washington <wash@wananchi.com>
To:        FBSD-Q <freebsd-questions@freebsd.org>
Subject:   Enteruser.pl - with attachments
Message-ID:  <20011107111037.C37545@ns2.wananchi.com>

next in thread | raw e-mail | index | archive | help

--NU0Ex4SbNnrxsi6C
Content-Type: multipart/mixed; boundary="1UWUbFP1cBYEclgG"
Content-Disposition: inline


--1UWUbFP1cBYEclgG
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

[Sorry I forgot to attach the files in the previous mail]

Hello list,

I'm experiencing a problem with the perl script referred in the subject. I
hope that there is someone already using it. My problem is just to get this
script to use the group that I have specified in pw.conf. I have tried mang=
ling
abit but no success. If it can be prodded to prompt for a group (there is s=
ome=20
section which seems to allow that although when I enable it it doesn't seem=
 to read
and accept my input) that would be really nice.
If it could also be modified to have the default shell in the Shell: [shell=
s] - as
in Shell: [no] that would also be neat.

Below is the output of a test session. I'm attaching my pw.conf and the ent=
eruser.pl
script just in case someone needs to take a quick look. The only mod I've d=
one to  =20
the perl script is to add the organization variable.


[root@ns2]#./enteruser.pl
                     Username: test4
                    Full Name: Test Account 4
            Password: [random] test4
                 Shell: [shells]


-Wash

S y s t e m s   A d m i n i s t r a t o r
--
                                              ~\\_                =20
 Odhiambo Washington                            \\\\              =20
 Wananchi Online Ltd.,                          `\\\\\            =20
 1st Flr Loita Hse, Loita Street                 |\\\\\           =20
 PO Box 10286,00100-NAIROBI,KE.                   \\\\\|__.--~~\  =20
 Fax: 254 2 313985-9                           _--~            /  =20
 Fax: 254 2 313922                           /~ //////  _-~~~~'   =20
 E-mail: wash@wananchi.com                  ('-//////-//          =20
 URL	: http://www.wananchi.com            //////(((-)          =20
 GSM: 254 72 743 223 / 254 733 744 121     /////"                 =20
                                        _///"                     =20

+++
Monday, n.:
	In Christian countries, the day after the baseball game.
		-- Ambrose Bierce, "The Devil's Dictionary"

--1UWUbFP1cBYEclgG
Content-Type: application/x-perl
Content-Disposition: attachment; filename="enteruser.pl"
Content-Transfer-Encoding: quoted-printable

#!/usr/bin/perl=0A#=0A# NOTE: Install Perl5 and reference #!/usr/local/bin/=
perl if you have an older=0A# version of FreeBSD=0A#=0A# This software is i=
ntended for distribution under the same terms and spirit=0A# as FreeBSD.=0A=
#=0A# This script was originally authored by Dan Howard <dannyman@dannyland=
.org>=0A# for EnterAct, LLC, 1998. (http://www.enteract.com/)=0A#=0Ause Fcn=
tl ':flock';=0A#use Getopt::Std;=0A=0A# Global, user-customizeable configs=
=0Amy $pw_path =3D '/usr/sbin/pw';=0Amy $pw_conf_path =3D '/etc/pw.conf';=
=0Amy $sendmail_path =3D '/usr/sbin/sendmail';=0Amy $welcome_message_path =
=3D '/etc/adduser.message';=0Amy $logfile =3D '/var/log/enteruser.log';=0Am=
y $organization =3D 'Wananchi Online';=0Amy $domain =3D `/bin/hostname`;=0A=
#my $lockfile =3D '/var/run/enteruser.LOCK';=0A=0A### Forward declarations =
###=0A# Main functions=0Asub enteruser;=0Asub queueuser;=0A# Queueuser help=
ers=0Asub queueadd;=0Asub queuelist;=0Asub queuedel;=0Asub queuedo;=0A# Com=
mon helpers=0Asub get_user_data;=0Asub print_user_data;=0Asub add_user;=0A#=
 UI=0Asub get_fullname;=0Asub get_password;=0Asub get_shell;=0Asub get_user=
name;=0A#sub get_billing_id;=0A#sub get_group;=0A#sub get_referral;=0A# Gen=
eric helpers=0Asub append_file;=0A=0A### START PROGRAM ###=0Aif( $< !=3D 0 =
) {=0A	print "You must be root to run $0!\n";=0A	exit -1;=0A}=0A=0A# Here's=
 an example of how you could use GetOpt to extend functionality, but I=0A# =
never was too keen on this example.  One possibility is to set various=0A# =
defaults for a queueuser operation, or change the path for the welcome=0A# =
message.=0A#=0A# One possibility that has excited me on occasion has been t=
he idea of setting=0A# input through the command-line, which could ease the=
 lives of advanced users=0A# somewhat, but not enough that I've bothered to=
 try.=0A#=0A# getopts('c');=0A# # -c is for curt, meaning no welcome messag=
e=0A# if( $opt_c ) {=0A# 	print "Will not send welcome message.\n";=0A# 	$w=
elcome_message_path =3D '';=0A# }=0A=0Aif( $0 =3D~ /queueuser/ ) {=0A	&queu=
euser();=0A}=0Aelse {=0A	&enteruser();=0A}=0A###  END PROGRAM  ###=0A=0Asub=
 enteruser {=0A	my %newuser;=0A=0A	my $y_or_n;=0A	=0A	%newuser =3D &get_use=
r_data;=0A	print "\nVerify User Information\n";=0A	print "-----------------=
------\n";=0A	&print_user_data(%newuser);=0A	print "\nIs this okay? (Y/n) "=
;=0A	$y_or_n =3D <>;=0A	if( $y_or_n !~ /^n/i ) {=0A		&add_user(%newuser);=
=0A	}=0A}=0A=0Asub queueuser {=0A	my @userqueue;=0A	my $choice;=0A=0Awhile(=
1) {=0A	my $yn;=0A=0A	print<<__MENU;=0A=0A   Please Select Operation=0A   -=
----------------------=0A   [A]dd a user to the queue=0A   [L]ist users in =
the queue=0A   [D]elete user from the queue=0A   [P]rocess users in queue=
=0A   [Q]uit this program=0A__MENU=0A		print "What would you like to do? ";=
=0A		$choice =3D <>;=0A		if( $choice =3D~ /^a/i ) {=0A			LAME: { # the LAME=
 kludge=0A				push @userqueue, &queueadd;=0A			}=0A			print "Add another? (=
Y/n) ";=0A			$yn =3D <>;=0A			goto LAME unless $yn =3D~ /^n/i;=0A		}=0A		el=
sif( $choice =3D~ /^l/i ) {=0A			&queuelist(@userqueue);=0A		}=0A		elsif( $=
choice =3D~ /^d/i ) {=0A			@userqueue =3D &queuedel(@userqueue);=0A		}=0A		=
elsif( $choice =3D~ /^p/i ) {=0A			@userqueue =3D &queuedo(@userqueue);=0A	=
	}=0A		elsif( $choice =3D~ /^q/i ) {=0A			if( @userqueue ) {=0A				print "T=
here are unprocessed users in your queue.\n";=0A				print "If you quit now,=
 they will be lost!\n";=0A				print "Do you really want to quit? (y/N) ";=
=0A				$choice =3D <>;=0A				if( $choice =3D~ /^y/i ) {=0A					exit(0);=0A	=
			}=0A			}=0A			else {=0A				exit(0);=0A			}=0A		}=0A		else {=0A			print "=
\nHuh?\n";=0A		}=0A	}=0A}=0A	=0A# Pretty much just enteruser, only we stay =
within queueuser=0Asub queueadd {=0A	my %newuser;=0A=0A	my $y_or_n;=0A	=0A	=
%newuser =3D &get_user_data;=0A	print "\nVerify User Information\n";=0A	pri=
nt "-----------------------\n";=0A	&print_user_data(%newuser);=0A	print "\n=
Is this okay? (Y/n) ";=0A	$y_or_n =3D <>;=0A	if( $y_or_n !~ /^n/i ) {=0A		r=
eturn {%newuser};=0A	}=0A}=0A=0Asub queuelist {=0A	my @userlist =3D @_;=0A	=
my $user;=0A=0A	for $user (@userlist) {=0A		printf("%8s %16s %10s %4s\n", =
=0A			$user->{username}, $user->{password},=0A			$user->{fullname}, $user->=
{shell});=0A	}=0A}=0A=0Asub queuedel {=0A	my @userlist =3D @_;=0A	my $goner=
;=0A	my ($i, $confirm);=0A=0A	&queuelist(@userlist);=0A	print "Which user d=
o you wish to remove? ";=0A	$goner =3D <>;=0A	chomp $goner;=0A	for $i ( 0 .=
. $#userlist ) {=0A		if( $userlist[$i]->{username} eq $goner ) {=0A			print=
 "\nConfirm User Deletion\n";=0A			print "---------------------\n";=0A			&p=
rint_user_data(%{$userlist[$i]});=0A			print "Remove this user from your qu=
eue? (Y/n) ";=0A			$confirm =3D <>;=0A			if( $confirm !~ /^n/i ) {=0A				sp=
lice(@userlist,$i,1);=0A				print "User $goner removed from queue.\n";=0A		=
	}=0A			else {=0A				print "Okay then, we'll leave this one alone.\n";=0A		=
	}=0A		}=0A	}=0A	return @userlist;=0A}=0A=0Asub queuedo {=0A	my @userlist =
=3D @_;=0A	my $i;=0A=0A	for $user (@userlist) {=0A		if( $user->{username} )=
 {=0A			print "\n>>> ADDING USER ", $user->{username}, ":\n";=0A			&add_use=
r(%{$user});=0A		}=0A	}=0A	return;=0A}=0A=0A# Self-explanatory ...=0Asub pr=
int_user_data {=0A	my %user =3D @_;=0Aprint<<__EOUD;=0A   username: $user{u=
sername}=0A   fullname: $user{fullname}=0A   password: $user{password}=0A  =
    shell: $user{shell}=0A__EOUD=0A}=0A=0A# Get each piece of user data, ca=
lling appropriate get_ function until it=0A# returns 1=0Asub get_user_data =
{=0A	my %user;=0A#	while( $user{group} eq '' ) { $user{group} =3D &get_grou=
p; }=0A	while( $user{username} eq '' ) { $user{username} =3D &get_username;=
 }=0A	while( $user{fullname} eq '' ) { $user{fullname} =3D &get_fullname; }=
=0A	while( $user{password} eq '' ) { $user{password} =3D &get_password; }=
=0A	while( $user{shell} eq '' ) { $user{shell} =3D &get_shell; }=0A	return =
%user;=0A}=0A=0A# Here's an example of a custom function used by EnterAct. =
 Here we ask=0A# additionally for a 'Billing ID' to be stored in the log=0A=
# sub get_billing_id {=0A# 	print "                   Billing ID: ";=0A# 	m=
y $billing_id =3D <>;=0A# 	chomp $billing_id;=0A# 	if( $billing_id =3D~ /^\=
d+$/ ) {=0A# 		return $billing_id;=0A# 	}=0A# 	print "I'm sorry, but I was =
hoping for a number.\n";=0A# 	return '';=0A# }=0A=0Asub get_fullname {=0A	p=
rint "                    Full Name: ";=0A	my $fullname =3D <>;=0A	chomp $f=
ullname;=0A	if( $fullname eq '' ) {=0A		return "J. Doe";=0A	}=0A	if( $fulln=
ame =3D~ /^[\w\s\.\&\']*$/ ) {=0A		return $fullname;=0A	}=0A	print "Names s=
hould be alphanumeric.\n";=0A	return '';=0A}=0A=0A# Here's another example =
of how you might want to specify going about setting=0A# group names.  This=
 is an EnterAct-specific example which prompts for a few=0A# different acce=
ptable groups.=0A# sub get_group {=0A# 	while(1) {=0A# 		print "Choose from=
: dialin, mailbox, loyola, nologin\n";=0A# 		print "                  Which=
 group? ";=0A# 		my $group =3D <>;=0A# 		if( $group =3D~ /^d/i ) {=0A# 			r=
eturn 'dialin';=0A# 		}=0A# 		elsif( $group =3D~ /^m/i ) {=0A# 			return 'm=
ailbox';=0A# 		}=0A# 		elsif( $group =3D~ /^l/i ) {=0A# 			return 'loyola';=
=0A# 		}=0A# 		elsif( $group =3D~ /^n/i ) {=0A# 			return 'nologin';=0A# 		=
}=0A# 	}=0A# }=0A=0A# This one I like.  It'll generate a random password if=
 none is entered, using=0A# an algorithm that results in something a little=
 easier to tell a customer=0A# over the phone than what pw generates but th=
at should still be quite=0A# unpredictable.=0A#=0A# If a password is entere=
d, it does a very basic sanity check on it to=0A# determine if it might be =
easily crack-able.=0Asub get_password {=0A	my ($file, $confirm);=0A	my @che=
ck_files =3D ('/etc/passwd', '/usr/share/dict/words');=0A	my @ary =3D ( 0 .=
. 9, 'A' .. 'Z', 'a' .. 'z', 'z', '!', '$', '%');=0A=0A	print "            =
Password: [random] ";=0A	my $password =3D <>;=0A	chomp $password;=0A	if( $p=
assword ne '' ) {=0A		foreach $file (@check_files) {=0A			if( (system ("/us=
r/bin/grep", "-qw", $password, $file))/256 =3D=3D 0 ) {=0A				print "Ewww, =
no.  That password is found in $file.\n";=0A				print "This password is ine=
xcusably lame, do you really want it? (Y/n) ";=0A				$confirm =3D <>;=0A			=
	if( $confirm !~ /^n/i ) {=0A					return $password;=0A				}=0A				else {=0A=
					return '';=0A				}=0A			}=0A		}=0A	}=0A	else {=0A		my $pw_len =3D rand=
(5)+6;=0A		for(1..$pw_len) {=0A			$password .=3D $ary[rand(@ary)];=0A		}=0A=
	}=0A	return $password;=0A}=0A=0A# Another custom function used at EnterAct=
.  This one actually got much more=0A# sophisticated with time.  Seen here =
is an earlier version, that could still=0A# be interesting.=0A# =0A# sub ge=
t_referral {=0A# 	my @ary =3D (=0A# 	    'Current customer',=0A# 	    'Word=
 of mouth',=0A# 	    'Additional account',=0A# 	    'Microcenter',=0A# 	   =
 'CNET',=0A# 	    'Newsgroups',=0A# 	    'Loyola',=0A# 	    'Byte By Byte',=
=0A# 	    'Chicago Computer Guide',=0A# 	    'Digital Chicago',=0A# 	    'N=
ational-Louis',=0A# 	    'Lake Forest College',=0A# 	    'Web',=0A# 	    'P=
hone book',=0A# 	);=0A# =0A# 	foreach $n (0..@ary-1) {=0A# 		print " ", $n+=
1, "\) $ary[$n]\n";=0A# 	}=0A# =0A# 	print "Enter referral numer or other: =
";=0A# 	my $referral =3D <>;=0A# 	chomp $referral;=0A# 	if( $referral =3D~ =
/^\d+$/ && $ary[$referral-1] ) {=0A# 		$referral =3D $ary[$referral-1];=0A#=
 	}=0A# 	return $referral;=0A# }=0A=0A# This function will determine what s=
hells are available in $pw_conf_path and=0A# offer these as choices=0Asub g=
et_shell {=0A	my($i, $shell, $shellstr, $default);=0A	$shellstr =3D `/usr/b=
in/grep ^shells $pw_conf_path`;=0A	$shellstr =3D~ s/.*?=3D\W*(.*)/$1/;=0A	c=
homp $shellstr;=0A	my @shells =3D split(/\W+/, $shellstr);=0A	$default =3D =
$shells[0]; # Default shell is first choice listed.=0A	$default or die "Not=
 enough shells in $pw_conf_path!";=0A	print "                 Shell: [$defa=
ult] ";=0A	$shell =3D <>;=0A	chomp $shell;=0A	$shell =3D $default unless $s=
hell;=0A	for $i ( 0 .. $#shells ) {=0A		if( $shell eq $shells[$i] ) {=0A			=
return $shell;=0A		}=0A	}=0A	print "\"$shell\" is not a valid shell.\n";=0A=
	print "Please select from among:\n   @shells\n";=0A	return '';=0A}=0A=0A# =
If you are using a more modern version of FreeBSD and want to use usernames=
=0A# greater than eight characters, you need to change this function.  Add/=
remove=0A# checks as desired.=0Asub get_username {=0A	print "              =
       Username: ";=0A	my $username =3D <>;=0A	chomp $username;=0A	$usernam=
e =3D~ tr/[A-Z]/[a-z]/;=0A	if( length($username) > 8 ) {=0A		print "No, tha=
t username is too long.\n";=0A		print "Usernames must be eight of fewer cha=
racters.\n";=0A		return '';=0A	}=0A	if( length($username) < 3 ) {=0A		print=
 "No, that username is too short.\n";=0A		print "Usernames must be three or=
 more characters in length.\n";=0A		return '';=0A	}=0A	if( $username !~ /^[=
a-z0-9]*$/ ) {=0A		print "No, that username's not good.\n";=0A		print "User=
names should consist solely of alphanumeric characters.\n";=0A		return '';=
=0A	}=0A	if( $username !~ /^[a-z]/ ) {=0A		print "I'm sorry, but usernames =
shouldn't start with numbers.\n";=0A		return '';=0A	}=0A	if( (system "/usr/=
bin/id $username 2> /dev/null > /dev/null")/256 =3D=3D 0 ) {=0A		print "Ouc=
h - that one's taken already.\n";=0A		return '';=0A	}=0A	if( (system "/usr/=
bin/grep -q ^$username: /etc/aliases")/256 =3D=3D 0 ) {=0A		print "Ouch - t=
hat one's claimed as a mail alias.\n";=0A		return '';=0A	}=0A	return $usern=
ame;=0A}=0A=0A# Calls pw to enter a user into the system.  Did you properly=
 configure=0A# /etc/pw.conf?=0Asub add_user {=0A	my %user =3D @_;=0A	my $lo=
gline;=0A	my $username =3D $user{username};=0A	my $fullname =3D $user{fulln=
ame};=0A	my $password =3D $user{password};=0A	my $shell =3D $user{shell};=
=0A#	my $group =3D $user{group};=0A=0A	my $oldbuf =3D $|;=0A	$| =3D 1;=0A=
=0A	# It's nice to finish what we start.=0A	local $SIG{INT} =3D 'IGNORE';=
=0A=0A	print "Running pw ... ";=0A	open( PW, =0A	 "| $pw_path useradd $user=
name -c \"$fullname\" -m -s $shell -h 0" )=0A#	 "| $pw_path useradd $userna=
me -c \"$fullname\" -g $group -m -s $shell -h 0" )=0A	 or die "$pw_path fai=
lure: $!";=0A	print PW $password, "\n";=0A	close PW or warn "$pw_path exite=
d on $?: $!";=0A	print "DONE!\n";=0A=0A	print "Creating public directories =
... ";=0A	system("/bin/mkdir", "/home/$username/public_html");=0A	system("/=
usr/sbin/chown", "-R", "$username.$username", "/home/$username/public_html"=
);=0A#	system("/usr/sbin/chown", "-R", "$username.$group", "/home/$username=
/public_html");=0A	print "DONE!\n";=0A=0A	if( -s $welcome_message_path ) {=
=0A		print "Queueing welcome message ... ";=0A		open( WELCOME, $welcome_mes=
sage_path ) =0A       		or die "Couldn't open $welcome_message_path: $!";=
=0A		open( MAIL, "| $sendmail_path -t " )=0A  		|| die "Couldn't open pipe =
to $sendmail: $0";=0A		local $SIG{PIPE} =3D sub { die "Couldn't open pipe t=
o $sendmail: $0" };=0A		select MAIL;=0A		print<<__MAIL;=0ATo: $username\@$d=
omain ($fullname)=0ASubject: Welcome to $organization!=0A=0A__MAIL=0A		whil=
e( <WELCOME> ) {=0A			# This is better than exec()'ing arbitrary code as ro=
ot, agreed?=0A			s/\$name/$username/g;=0A			s/\$fullname/$fullname/g;=0A			=
s/\$password/$password/g;=0A			print unless /^#/;=0A		}=0A		close MAIL || d=
ie "Error completing mail operation: $0";=0A		select STDOUT;=0A		print "DON=
E!\n";=0A	}=0A=0A	print "Logging ... ";=0A	$logline =3D localtime() . " $0 =
" . "$username (" . (getpwnam($username))[2] . "/" . (getpwnam($username))[=
3] . ") \"$fullname\"";=0A#	$logline =3D localtime() . " $0 " . "$username/=
$group (" . (getpwnam($username))[2] . "/" . (getpwnam($username))[3] . ") =
\"$fullname\"";=0A	&append_file($logfile, $logline);=0A	print "DONE!\n";=0A=
=0A	$| =3D $oldbuf;=0A}=0A=0Asub append_file {=0A	my($filename,$line) =3D @=
_;=0A=0A	open(FH, ">>$filename") or warn=0A		"Can't open $logfile: $!";=0A	=
flock(FH,LOCK_EX);=0A	seek(FH, 0, 2);=0A	print FH $line, "\n";=0A	close(FH)=
;=0A	flock(FH, LOCK_UN);=0A}=0A
--1UWUbFP1cBYEclgG
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pw.conf"

defaultpasswd		no
reuseuids		yes
reusegids		no
#nispasswd		no
skeleton		no
newmail			/etc/adduser.message
logfile			/var/log/newusers.log-`/bin/date +%Y-%m-%d`
home			/home
shellpath		/bin:/sbin:/usr/local/bin:/usr/compat/linux/bin
shells			sh, csh, bash, tcsh, ksh, zsh, no, date
defaultshell		no
defaultgroup		1004
#extragroups		wheel, staff
#defaultclass		no
minuid			1000
maxuid			1000 - 65534
mingid			1000
maxgid			1000 - 65534
#expire_days		no
#password_days		no



--1UWUbFP1cBYEclgG--

--NU0Ex4SbNnrxsi6C
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iD8DBQE76Ox9n7LIsuxjem8RAppoAJ9Z3vW9+fANOEDdQ4Y5Fp776z4e1QCePN/+
Ya0VAXgM4vTsW5IFP9kKgBw=
=DokJ
-----END PGP SIGNATURE-----

--NU0Ex4SbNnrxsi6C--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-questions" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011107111037.C37545>