Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

useradd with perl and cron

by true (Pilgrim)
on Jun 11, 2003 at 06:01 UTC ( [id://264964]=perlquestion: print w/replies, xml ) Need Help??

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

I run a virtual hosting environment. I have a perl(CGI) control panel which runs over SSL with htaccess. The control panel let's users modify their email handlers (forwards and stuff). I've added the ability for a user to add another user to the system so the virtual host can add their own mailboxes. Each new user added is the username with a number at the end. After i gather my new user data, i pass a request from the CGI to a root perl script (called root.pl). The root script is controlled by cron. After a series of checks, root.pl adds the user to the system by running useradd. Or at least it tries. I am only getting errors when cron runs the root.pl. If i run root.pl from ssh manually it adds the user returning '0' to my log. When i let cron execute root.pl. The user is not added and i get the error 65280 returned.

Here's what root.pl does to add the user.

#!/usr/bin/perl use strict; use Crypt::Passwd; my $home = "/var/www/grpname/"; my $user = "User23"; my $password = "xR3rts"; my $grp = "grpname"; my $cpass = unix_std_crypt($password, "salt"); my $re = system("useradd -g $grp -p $cpass -d $home $user"); print "ADDUSER:$re\n"; exit;
I know it is running as root with cron b/c i've tested with:
my $real = getpwuid($<); my $effective = getpwuid($>);
Both return root to my log whether running from cron or manually with ssh. I've looked for the error 65280 with no luck.

Any ideas as to why im getting 65280 error when cron tries? Thanks for reading.

jtrue

Replies are listed 'Best First'.
Re: useradd with perl and cron
by Zaxo (Archbishop) on Jun 11, 2003 at 06:15 UTC

    I suspect the reason for cron trouble is that cron gets a very small restricted set of environment variables. Set PATH and such in your crontab.

    More important, I would shy from this project. Setting up user mail aliases should not involve letting users grant shell accounts to anyone they take a notion to.

    After Compline,
    Zaxo

Re: useradd with perl and cron
by true (Pilgrim) on Jun 11, 2003 at 06:25 UTC
    putting the full path of useradd solved the problem. "whereis useradd" told me where it was. The script could not find useradd. Also, root.pl should set the new user's shell parameter(-s) to "/bin/false". This turns off shell access to the new user.

    jtrue

      What about the case where two virtual users want to be info@mydomain.com and info@over.here.com? Or joe or john or blah???

      In this case you (possibly) need a single info, joe, john, etc account on the box (so it will accept the mail) but you need to modify the virtuser table for sendmail (if that is what you are using) to redirect the info@... mail to the correct users. Note procmail will not work as the mail headers on the envelope are stripped by the time procmail gets to see a given message.

      FYI there are many ways to configure sendmail to accept and redirect mail. Maybe you should RTFM as you are definitely not the first person to strike this problem, and there are several ways to skin this particular cat. As suggested by Zaxo while your solution will work it is not highly recommended. Procmail is also a useful widget in a number of circumstances. For example you can direct all mail for *@domain.com to a single shell account, have procmail intercept it and redistribute it to any number of email accounts - either local or remote. Voila - infinite virtual POP boxes without infinite shell accounts.

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: useradd with perl and cron
by thor (Priest) on Jun 11, 2003 at 12:30 UTC
    I don't know for sure, but does SSH or useradd require a tty to be sitting on the receiving end? I know that the passwd program is like that. If that's the case, I'd explore the Expect module.

    thor

      No they don't. Nor does passwd need a tty. You can run a script like this without any tty or user input.

      #!/usr/bin/perl -w use strict; $|++; my $HOME_DIR = '/home/'; my $MAIL_DIR = '/var/mail/'; my $CRAM_FILE = '/etc/cram-md5.pwd'; my $USERADD_BIN = '/usr/sbin/useradd'; my $PASSWD_BIN = '/usr/bin/passwd'; my $PASSWD_FILE = '/etc/passwd'; my $HTPASSWD_BIN = '/usr/bin/htpasswd'; my $HTPASSWD_FILE = '/home/www/.htpasswd'; print "Username: "; chomp(my $user = <>); if(`grep /$user:/ $PASSWD_FILE`) { print "Username '$user' already exists! Continue (default=y) [y/n] +: "; exit if <> =~ /n/i; } else { `$USERADD_BIN "$user"`; } print "Shell Password: "; chomp(my $shellpwd = <>); if ($shellpwd) { open PWD, "|$PASSWD_BIN --stdin $user" or die "Can't open pipe to +$PASSWD_BIN $!\n"; print PWD $shellpwd, "\n"; close PWD; } else { print "No shell account password will be added!\n"; } $shellpwd ||= 'password'; print "POP3 password (default='$shellpwd'): "; chomp(my $pop3pwd = <>); print "Shell and POP3 passwords will be the same!\n" unless $pop3pwd; $pop3pwd ||= $shellpwd; # avoid duplicate entries in cram-md5.pwd open PWD, "<$CRAM_FILE" or die "Can't read $CRAM_FILE $!\n"; my @old_cram = grep { ! /$user\t/ } <PWD>; close PWD; print "Adding POP3 password to /etc/cram-md5.pwd\n"; open PWD, ">$CRAM_FILE" or die "Can't write $CRAM_FILE $!\n"; print PWD @old_cram, "$user\t$pop3pwd\n"; close PWD; print "Add to .htaccess (default=y) [y/n]: "; unless ( <> =~ m/n/i ) { `$HTPASSWD_BIN -b $HTPASSWD_FILE $user "$pop3pwd"`; }

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        You assume that all Unicies were created equal. That does not work on my Solaris 5.6 machine, whereas I assume that you're using some flavor of Linux judging by the GNU style '--stdin' parm.

        thor

Re: useradd with perl and cron
by nimdokk (Vicar) on Jun 11, 2003 at 12:53 UTC
    You may want to explicitly set your path in $ENV{PATH}='/path/to/useradd'; or even better, remove everything from the %ENV hash, then explicity give the path to the useradd program in the system() call. You might want to check out the chapter on Security in Programming Perl. Also, to get a good return code from the useradd() program, you might check $? and shift it as:

    $returncode=$?>>8;

    Read the perldocs on system() for further information on obtaining a good return code.

    Hope that helps :-)

    "Ex libris un peut de tout"

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://264964]
Approved by sauoq
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2024-04-25 04:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found