Tuesday, July 20, 2010

Episode #104: Fricken' Users

Hal remembers fondly

I remember it as if it were only last week. There we were, having a quiet little celebration for our 100th Episode on the PaulDotCom Podcast. A little trash talk, some fart jokes, and, of course, Ed's big announcement ("I quit! Hal wins!"). And then one of the folks on the IRC channel had to harsh our mellow by pointing out that we've never done an Episode about adding users via the command line. Well we're not the sort of people to take a challenge like that lying down (at least when we're sober)!

Interestingly, the useradd command is one of the few fairly consistent commands across all flavors of Unix-like operating systems. I've used essentially identical useradd commands to add users on Linux, Solaris, and BSD. Here's a sample of the typical usage:

# useradd -g users -G adm,wheel -c 'Hal Pomeranz' -m -d /home/pomeranz -s /bin/bash pomeranz

The "-g" option is used to specify the primary group for the account and "-G" can be used to set supplemental group memberships in /etc/group. "-c" sets the comment (aka full name or GECOS) field in /etc/passwd. "-d" specifies the user's home directory, and "-m" tells useradd to make this directory (don't use "-m" if the home directory is on a share that you don't have root write access to-- you'll have to make it by hand). "-s" specifies the shell. The final argument is always the name of the user, and somehow I usually manage to forget this vital piece of information the first time I run the command. Stupid computers! Why can't they do what I want them to do instead of what I tell them to do?

Note that the useradd command does not set the user's password. While there's normally a "-p" option on most useradd commands to specify a hashed password string on the command line, this is not terribly secure even though the password is encrypted (hello, password crackers!). If you don't specify the password, then the account will be created with a locked password which you will need to set with the passwd command.

Actually, there are typically defaults for some or all of the parameters given on the command line above, though what is defaulted and the values of those defaults can vary widely from Unix variant to Unix variant. This is why I tend to use commands like you see above that are very explicit about what I want to set. "useradd -D" will show you the defaults available on your platform. Here's the output from one of my Linux systems:

# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes

You can see the defaults for GROUP and SHELL. The directory given by the HOME parameter is obviously a prefix, so if you don't specify a homedir with "-d", then the default in this case will be "/home/<username>". SKEL is actually worth noting-- any files you place in this directory will automatically be copied into the new user's home directory. This makes it easy to give your new users customized .profile, .bashrc, and other start-up files for your environment.

So how can you change these defaults? Well, that's where things start getting a little squirrelly. Generally, there are options that can follow "-D" in order to reset these defaults. For example, "useradd -D -k /usr/local/etc/skel" would change the default location of the SKEL parameter. But on the Red Hat machine where I'm preparing these examples, there's no option for setting the value of CREATE_MAIL_SPOOL. That means we need to go and edit the configuration file for useradd directly to change this parameter. Typically the path to this file is given in the system manual page (it's /etc/default/useradd on Red Hat systems). You're going to need to look at the manual page anyway, because the defaults and the option letter to reset them vary so widely from OS to OS.

And, yes Virginia, there is a userdel command for removing users:

# userdel -r pomeranz

The "-r" option tells userdel to go ahead and remove the user's home directory when cleaning up the account. Some sites prefer not to do this, which is why it's an option instead of the default behavior. Note that userdel will got through /etc/group and clean up all of the user's supplemental group listings.

The only problem with useradd/userdel is that they generally only work on the local user database on the system. If you're using LDAP or some other networked user database, then you'll have to use an alternate tool. But in these cases, the user management software you're using will come with some sort of application-specific user adding/removing tool.

Let's see what Tim can come up with this week...

Tim creates an army:

Since Ed is gone, this is a perfect week to conjure up my own army of Eds. We can use the Windows shells to create local computer accounts, as well as domain accounts. First, the local machine.

We can start off with the good old net user command. This command works in cmd and in PowerShell.

C:\> net user Ed Tim15myHero! /add


This creates a user named Ed, with a password of Tim15myHero! on the local machine. What happens if you try to create a user with a longer password?

C:\> net user Ed This15aLOOOOOONGpassword /add
The password entered is longer than 14 characters. Computers
with Windows prior to Windows 2000 will not be able to use
this account. Do you want to continue this operation? (Y/N) [Y]: Y


Windows barks about backwards compatibility. This warning is related to the password storage on older machines. Specifically, the LAN Manager (LanMan or LM) Hash which can only handle 14 characters. As a side note, when creating passwords passphrases in Windows it is advisable to use one that is at least 15 characters long so that Windows can't store the password in this form. Windows still stores the LM Hash in versions prior to Vista and Windows 2008.

Ok, so back to creating the army.

When we create the users the password was typed so it was visible on the screen. If we use * as the password, then you will be prompted to enter the password and it isn't visible on the screen.

C:\> net user Ed * /add
Type a password for the user:


Users can also be added to the Windows domain.

C:\> net user Ed Tim15myHero! /add /domain


Deleting the users is pretty easy too.

C:\> net user Ed /delete
C:\> net user Ed /delete /domain


PowerShell v2 gives us the ability to create users on the domain. However, it does require a Windows 2008 R2 domain controller.

This cmdlet gives us a lot of power to set a wide range of AD attributes, but we won't use them all. Let's keep it simple and create an account and set a few of the most common attributes.

PS C:\> New-ADUser -SamAccountName edskoudis -GivenName Ed -Surname Skoudis -DisplayName "Skoudis, Ed" 


This cmdlet allows us to set the common attributes. If there is an attribute you would like to set upon creation of the account that isn't standard, you can use the OtherAttributes parameter to access the attribute.

PS C:\> New-ADUser edskoudis -OtherAttributes @{extendedAttribute1="gone"}


We can't just set the account password since the AccountPassword expects the password to be a secure string. It takes a bit of extra effort to use a clear text password in this command let. To securely set the password of the account, we can nest the cmdlets so we will be prompted

PS C:\> New-ADUser edskoudis -AccountPassword (ConvertTo-SecureString "Tim15myHero!" -AsPlainText -force)


The AsPlainText parameter tells the cmdlet that a plain text string will be used and it must be used with the -Force option.

Now that we can create accounts from the command line, I can automate the creation of my Ed army.

PS C:\> 1..5000 | % { New-ADUser "ed$_" }