Saturday, December 03, 2005

Adding Multiple Users and Setting Quotas on FreeBSD

I am setting up a VM for students in my USENIX LISA classes next week. While I would prefer students to use tools on their own laptops to analyze packet traces I provide, I realize some may not be able to get all of the requisite software working. Rather than leave them stranded, I am deploying a FreeBSD 6.0 VM that will run on my laptop. Students can SSH to the VM and analyze traces there. Alternatively, I plan to create a simple VM that students can run in VMware Player.

I decided I would create 33 student accounts, named student0 - student32. I would perform demos as student0. I was not about to run adduser 33 times to create the necessary accounts, so the following shows how I added those accounts using a simple shell script.

First I created a default configuration file using the -C switch.

samsonov:/root# adduser -C
Login group []:
Enter additional groups []:
Login class [default]:
Shell (sh csh tcsh bash nologin) [sh]: bash
Home directory [/home/]:
Use password-based authentication? [yes]:
Use an empty password? (yes/no) [no]:
Use a random password? (yes/no) [no]:
Lock out the account after creation? [no]:
Pass Type : yes
Class :
Groups :
Home : /home/
Shell : /usr/local/bin/bash
Locked : no
OK? (yes/no): yes
Re-edit the default configuration? (yes/no): no
Goodbye!

Next I tested out creating the student0 account using the pw command. The syntax says add user student0, with password same as the username (-w yes), create the home directory /home/student0, and set student0 as the GECOS field. (Obviously a student0/student0 username/password combination is not suitable in production, but it's just what I want in the classroom.)

samsonov:/root# pw useradd student0 -w yes -m -c student0

Now I test to see that the process worked by checking for a new /etc/passwd entry and the appropriate home directory.

samsonov:/root# grep student0 /etc/passwd
student0:*:1002:1002:student0:/home/student0:/bin/sh
samsonov:/root# ls -al /home/student0/
total 20
drwxr-xr-x 2 student0 student0 512 Dec 3 21:00 .
drwxr-xr-x 5 root wheel 512 Dec 3 21:00 ..
-rw-r--r-- 1 student0 student0 767 Dec 3 21:00 .cshrc
-rw-r--r-- 1 student0 student0 248 Dec 3 21:00 .login
-rw-r--r-- 1 student0 student0 158 Dec 3 21:00 .login_conf
-rw------- 1 student0 student0 373 Dec 3 21:00 .mail_aliases
-rw-r--r-- 1 student0 student0 331 Dec 3 21:00 .mailrc
-rw-r--r-- 1 student0 student0 797 Dec 3 21:00 .profile
-rw------- 1 student0 student0 276 Dec 3 21:00 .rhosts
-rw-r--r-- 1 student0 student0 975 Dec 3 21:00 .shrc

It looks like pw worked as advertised. Next I write a simple while loop shell script to create users student1-student32.

samsonov:/root# cat add_multiple_users.sh
#!/usr/local/bin/bash
i=1
while [ $i -lt 33 ]
do
pw useradd student$i -w yes -m -c student$i
i=$[$i+1]
done

After running the script, I see my new users are added.

samsonov:/root# tail /etc/passwd
student23:*:1025:1025:student23:/home/student23:/bin/sh
student24:*:1026:1026:student24:/home/student24:/bin/sh
student25:*:1027:1027:student25:/home/student25:/bin/sh
student26:*:1028:1028:student26:/home/student26:/bin/sh
student27:*:1029:1029:student27:/home/student27:/bin/sh
student28:*:1030:1030:student28:/home/student28:/bin/sh
student29:*:1031:1031:student29:/home/student29:/bin/sh
student30:*:1032:1032:student30:/home/student30:/bin/sh
student31:*:1033:1033:student31:/home/student31:/bin/sh
student32:*:1034:1034:student32:/home/student32:/bin/sh

samsonov:/root# ls /home/
.snap student13 student2 student26 student32
richard student14 student20 student27 student4
student0 student15 student21 student28 student5
student1 student16 student22 student29 student6
student10 student17 student23 student3 student7
student11 student18 student24 student30 student8
student12 student19 student25 student31 student9

At this point I have my users. Now I turn to setting up per-user quotas. I do not want a rogue user to decide to use up all of /home, so I need a mechanism to enfore a per-user disk usage quota. I do that with file system quotas.

I have to add 'options QUOTA' to my kernel configuration file, and then rebuild the kernel to enforce quotas. I also need to add the following to /etc/rc.conf:

enable_quotas="YES"
check_quotas="NO"

After rebooting, quotas are enabled.

samsonov:/root# quota -v
quota: /home/quota.user: No such file or directory
Disk quotas for user root (uid 0): none

Now I can set a quota for student0. I set a soft limit of 100MB and a hard limit of 120MB.

samsonov:/root# edquota -u student0
edquota: creating quota file /home/quota.user

Quotas for user student0:
/home: kbytes in use: 0, limits (soft = 100000, hard = 120000)
inodes in use: 0, limits (soft = 0, hard = 0)

Checking the quotas, I see they are working.

samsonov:/root# quota -v student0
Disk quotas for user student0 (uid 1002):
Filesystem usage quota limit grace files quota limit grace
/home 0 100000 120000 0 0 0

The easiest way to set the same quotas for students1-32 is to use the -p option to specify a user whose quota one wants to duplicate, followed by the UIDs of the users to which the new quota will be applied.

samsonov:/root# edquota -p student0 1002-1034

Now I check to see if student1 has the same quotas as student0.

samsonov:/root# quota -v student1
Disk quotas for user student1 (uid 1003):
Filesystem usage quota limit grace files quota limit grace
/home 0 100000 120000 0 0 0

All done!

1 comment:

Anonymous said...

A minor suggestion for the add_multiple_users.sh script;
it can be simplified by the use of the often forgotten
jot(1) command (at the expense of some portability):

for i in `jot 33 1`
do
pw useradd student$i -w yes -m -c student$i
done