in reply to CGI script review

You allow newlines in $fullname (they match \s), which is probably a really bad idea. You probably want an explicit space there (TAB and CR characters in your passwd file don't sound like any fun either). Fortunately, since you don't allow a colon I couldn't find a way to leverage this into a root login.

Ditto for $passwd, although that's not so bad from a security standpoint (since you crypt it anyways).

Keep in mind that anybody logged into the system running ps can see all of those command-line parameters, including the password. Better to pass them on a filehandle.

Some part of this system must run as root. Is it your CGI script, or adduser.pl? If adduser.pl, how do you prevent other users from running this?

Your pattern [a-z0-9-._] looks error prone. I would either move the - to the end, or else escape it with a backslash. Otherwise small changes could turn it into a range of characters, with possibly unfortunate consequences.

Not allowing users to have symbols in their passwords makes them noticably less secure, simply because it reduces the possible characters in the password. All of my passwords have symbols in them, and I get extremely annoyed when I can't use symbols in passwords.

There's a race condition; the user could not exist at the time getpwnam runs, but exist by the time adduser.pl runs. As long as adduser.pl handles this, it won't cause serious problems, but you could fix it altogether by returning a specific error code if the user already exists, and detecting this and giving an appropriate error message.

All in all, though, a pretty good job. Use of -T is very important, along with -w, use strict, and the multiple-argument form of system. Mails are sent with sendmail instead of /bin/mail which is good---/bin/mailhas been prone to shell escapes in the past and may still be. As somebody else said, you'll want to run this over SSL, but it looks like you already are.