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

Hi All,

I am writing a script to create user accounts on my server from the web. As the webuser account on my server has no access to the adduser command, i write the data of the user account to a file, and then another script (run by cron) comes along and processes the data.

Currently there is no way a user can tell if their desired username is taken, until the second script runs and returns and error.

The only way i have thought about getting around this is to get the first script to take a shot of my /home directory and compare the list returned (all users have folder in /home on my server) with the contents of my vairable $username (which will contain the persons desired username), if there is a folder in /home named the same as the contents of $username then return an error.

Any ideas on how to go about this? I am stuck.

Replies are listed 'Best First'.
Re: Does this user exist?
by grinder (Bishop) on Jan 01, 2003 at 15:58 UTC

    Some users will not have a home directory under /home. Much better is to see whether they exist in /etc/passwd. For this, you need to use getpwnam. For instance:

    my $dir = ((getpwnam($user))[7]);

    ... will return the home directory, wherever it may be, of the user. If getpwnam returns undef, then you are certain that the user does not exist on your system. (But think a while about what happens when two people ask to register the same name)...


    print@_{sort keys %_},$/if%_=split//,'= & *a?b:e\f/h^h!j+n,o@o;r$s-t%t#u'
Re: Does this user exist?
by pfaut (Priest) on Jan 01, 2003 at 16:13 UTC

    I will assume you are writing a set of utilities to aid in your system management processes and have taken the proper steps to secure this application from anyone but those authorized to use it. You have done this, right? Good. Because if this is unprotected or on a public web server, you are just asking to get hacked. And, of course, you are checking every argument that comes in from the form for length and invalid characters, right?

    The ability to look up account information is built into perl. Use the getpwnam() function to look up an account by name. But you may still have a race condition. If two people request the same account name between invocations of the cron job, you can still end up with duplicate account names. You will have to also search the list of pending account creations. You should also set up some interlocks to make sure two copies of your application aren't performing searches at the same time.

    Personally, I wouldn't allow this type of stuff on a network I managed. Web apps are too easily hacked. Use ssh and be absolutely certain of what accounts are being created on your machine and how.

    --- print map { my ($m)=1<<hex($_)&11?' ':''; $m.=substr('AHJPacehklnorstu',hex($_),1) } split //,'2fde0abe76c36c914586c';
Re: Does this user exist?
by traveler (Parson) on Jan 01, 2003 at 16:14 UTC
    grinder is correct. Anonymous Monk is, too. Be afraid. Be very afraid. One additional thing to consider is to check the usernames for validity. You do not want a user asking for the name evil::0:0: (of course, the 'name' doesn't matter).

    Do the people really need full accounts? Can you create web-accounts (e.g. using htpasswd/.htaccess in Apache)?

    BTW, using folders in /home is not a correct algorithm: at least root does not have a home directory there.

    HTH, --traveler

Re: Does this user exist?
by gjb (Vicar) on Jan 01, 2003 at 17:20 UTC

    This should do what you want:

    opendir(DIR, '.') || die("Can't open dir"); my @dirs = grep(/^\w/, readdir(DIR)); closedir(DIR); if (grep(/^$username$/, @dirs)) { print "yes\n"; }
    Hope this helps, -gjb-

Re: Does this user exist?
by Anonymous Monk on Jan 01, 2003 at 15:56 UTC

    You're just begging to get hacked. How about not doing this at all, eh? Your userlist is normally found in /etc/passwd and the task itself is pretty trivial. The problem is that you should already be pretty senior before attempting to write stuff like this. You're just making it all that more likely for someone to come along and paste a j00 @r3 h@xored on your home page (among other more nasty things).

      This is a pretty blatant troll, but I want to spell that out so that the questioner doesn't get cowed.

      Yes, it takes special care to write a secure web app ( especially one that adds user accounts ), but it doesn't take a "senior" programmer, just a humble one who isn't afraid to ask for help and follows some well-established practices, like using taint and running system commands from a cron job, instead of the script itself - exactly what the questioner is doing.

      See below for a more reasoned answer.

        Actually Re: Does this user exist? was me. Originally I was going to be funny but in my sleep deprived state it wasn't at all. I'm still very, very tired but oh well. If you feel like sending a '--' where it counts then plonk it here. [Update: Oh yeah, the anonymous monk was part of the joke and I was already writing the node when I realized it didn't need to be anonymous anymore.]

        The general attitude is similar to that expressed regarding symbolic references. People who ask that sort of question that way are defacto not qualified to write that piece of software. I don't know that I'd be qualified to write that either. The whole idea of having a web accessible user-creation system or really anything at all tied into the system is deep, deep mojo and difficult to get right.

        Or put another way - this system is a way of removing several layers of authentication and access control. Many normal system protections are just being completely set aside (by going through this web->cron interface). Doing this right will take some serious meditation and knowledge of the host environment.


        Fun Fun Fun in the Fluffy Chair

      Please,

      I did not ask of your opinions on the security of this script, but merely help on a certain aspect of it. Yes i am running taint, yes i have regexps on user input - and NO this is not a live web system.

      If my server gets hacked or trashed, its my fault i know.

      ALL of my users have directories in /home, can someone please shed some light on how to compare the data in $username with what is in the /home directory, and return an error if the folder/username already exists.

        Oh well that's easy: carp "Directory found" if -e "/home/$username";. The thing is, if you couldn't code that then I don't think you're competent to code the rest of the sytem.


        Fun Fun Fun in the Fluffy Chair