FreeBSD new user login script

I am a beginner programmer and would like to know where to start to modify the login process so that a user can login as username new password new and have it prompt user for username and password and nothing else and then create said user account on the system so they can ssh back in and login with the newly created account. A friend had accomplished this in perl but that was many moons and several versions of perl ago. Security is at the front of this project idea as this will be part of a free shell project aimed towards hackers.

Any shoves in the right direction would be welcomed.

This migh be a good start, but you probably want to research what login does (eg running /etc/profile and the like).

#!/bin/bash
trap 'exit 0' 1 2 3 15
printf "Username: "
read touser
trap - 1 2 3 15
if [ "$touser" = "new" ]
then
    echo "Create a new user account here"
else
    exec su - $touser
fi

The create of user account stuff is usually pretty system specific but you should aim at using system tools (eg adduser).

It dosn't seem like security is of a major concern here, but you should test well to ensure the user can't break out into a root shell from the createuser part of the script (for example using CTRL-C at a prompt).

1 Like

I'm hoping you mean 'hacker' in the good sense. I know, I know -- corruption of a perfectly good term, but that's something beyond our control.

If you don't have sudo installed, install it, you'll need it.

What shells do you have available?

The process I'd envision is
1) User logs into the 'new' account. Instead of running a shell, their account is configured(via usermod) to run a shell script as its login shell like this:

while [ -z "$NEWUSER" ]
do
        printf "New username: " >&2
        read NEWUSER || exit 1
        if ! echo "$NEWUSER" | grep "^[a-z_][a-z0-9_-]*$" > /dev/null
        then
                echo "Usernames must be a-z_-" >&2
                NEWUSER=""
                continue
        fi

        if grep "^${NEWUSER}:" /etc/passwd > /dev/null
        then
                echo "${NEWUSER} already exists" >&2
                NEWUSER=""
                continue
        fi
done

exec sudo /usr/local/sbin/newuser.sh "$NEWUSER"

And the contents of /usr/local/sbin/newuser.sh:

#!/bin/sh

useradd "$1"

passwd "$1" || userdel "$1"

and you'd need this line in sudoers:

new ALL=NOPASSWD:  /usr/local/sbin/newuser.sh

which should permit the new user to run /usr/local/sbin/newuser.sh as root but nothing else.

This code may not be perfect or complete.

1 Like

thanks for the quick replies and to clear it up I mean the good sense of the word hacker. not crackers who break system security. This project is for those that want to fine tune their unix skills.

Sounds like a good project to me. I've considered such a thing but I'm having a hard time striking a balance between giving people sufficient access and preventing them from setting up botnets etc in it. All someone needs to do that is bash, cat, and chmod...

1 Like

in the past we ran this project for several years during bsd 4.x days and we blocked a lot of processes from being executed such as irc clients and bots and eggdrops. We had to go as far as to make the logon banner display an IRC warning in romainian because of the high amount of traffic from that country. I am hoping this project will take off again in the first few months of inception before we had about 2400 users. We do a form of hardware logging with an old dot matrix line feed printer and that is the only logging we really do to cover our asses in case we do get a rogue hacker that decides to abuse privledges.

---------- Post updated at 11:43 PM ---------- Previous update was at 05:44 PM ----------

I was trying the method you posted but im using freebsd 8.2 there is no useradd or usermod to monkey with so I am at a slight brick wall of how to proceed with this method. I initially tried switching it out with adduser which ends up prompting a new user with far too many options. hehe. I also have many shells available such as bash and sh

Are you sure there's no useradd? Not having that is very weird.

[edit] ah, you're right, it doesn't. But 1.25 seconds of googling "freebsd useradd" found the equivalent in the very first hit.

...Then I "man pw", and found the usage of (pw) user add is a little different from the standard ones: 
pw [-V etcdir] useradd [name|uid] [-C config] [-q] [-n name] [-u uid]
   [-c comment] [-d dir] [-e date] [-p date] [-g group] [-G grouplist]
   [-m] [-k dir] [-w method] [-s shell] [-o] [-L class] [-h fd | -H fd]
   [-N] [-P] [-Y]

In FreeBSD, it should be "pw useradd username -g groupname", and not "pw useradd -g groupname username". 

I had noticed 'pw' as the replacement for useradd I just was not familiar with the syntax and how to implement it in this function. Thanks so much Corona for your invaluable help on this. I will accredit you for it when my project is up and running. This evening I will be working on the login script to see how I can get this accomplished with security in mind as I do not want a user to be able to break out to a root shell.

Trapping signals as Chubler_XL noted would be a good idea.

But when you set new's login shell to a shell script rather than anything new's .profile, it's a noninteractive shell -- nothing to break out into. All they'll do when they try is kill their own login. You don't even need to give new a home directory...

There'd still be a potential for injection attacks, i.e. feeding crafted strings into your script, or interception, like other users snooping on live registrations.

That's why the script I wrote tries so hard to sanitize the username input. I'd do more on top of that too -- enforce a minimum and maximum number of characters, for instance. That's also why I never read the password myself or pass it around between programs -- that's entirely passwd's job(or the BSD equivalent.) since it can do it in a secure manner, reading it from the terminal direct. You could pass the username into your root-privileged add-user script on standard input if you didn't want it visible on the commandline -- for a brief time during registration, the username might show up on ps...

If you want to enforce password constraints, that should be done in passwd too and not in your script. Never pass around passwords if you can possibly help it, they should go directly from the terminal to the login system because that's a secure channel.

1 Like

Thanks again for the help I believe I have this implemented and functional now by using pw in place of useradd.