Enforcing environmental limits

User limits

Controlling user limits should not only cover the resources being used, it should also encompass environmental limitations on the account in general. This article describes what user limits should cover and also demonstrates the concepts of limits with examples.


David Tansley (david.tansley@btinternet.com), Systems Administrator, Ace Europe

David TansleyDavid Tansley is a freelance writer. He has 19 years of experience as a UNIX administrator, using AIX the last 9 years. He enjoys jogging and then relaxing by watching Formula 1, but nothing beats riding and touring on his GSA motorbike with his wife.

developerWorks Contributing author

11 April 2014

Also available in Russian


This article describes the following topics:

  • What resource limitations to consider for different environments
  • Popular ulimit attributes
  • Shell restriction
  • Disk quotas

What limitations should be imposed?

When deciding on limits for a user, try to consider the type of account and what the account is being used for. For example, if it is an application owner account, serious consideration must be undertaken on increasing some of the ulimit settings, as you do not want error messages complaining about lack of open files or unable to write large data (amounts) to a disk. What seems to be quite an occurrence in the last few years is running out of memory. The need to raise the RSS (memory) due to a low ulimit restriction is quite a regular task. If the account is a third-party support who just wants to review logs files, then I would not be looking at ulimit resources, but rather a limit on where the user can wander around the system. I would consider a restricted shell, or a chroot Secure File Transfer Protocol (SFTP) or File Transfer Protocol (FTP) environment. If the user account was an internal support person, well they are pretty much going to try and convince you that they require unlimited resources to support this application. Certainly consider increasing the core dumps and the file size values for these types of users first.

Be realistic on what resources they get, so often you hear a call for ulimited access. It is so easy to apply a quick fix and give developers unlimited resources but take a moment of pause before going down this path. Before long, you will have many accounts with unlimited resource limits. At best, this will affect the performance of the system trying to allocate the resources, and at worst, the system could come down to its knees.

What ulimits do I have set?

Reviewing the defaults limits stanza in /etc/security/limits. These are the default settings that the user login account will use. However, these values can be overridden by specifying different ulimit values on a per user basis. Each user will have a separate stanza if any of the default values are overridden for a user. These ulimit values can be changed through System Management Interface Tool (SMIT) or chuser, or manually editing the limits file. There are two types of ulimit values, soft and hard. The soft values are displayed using the ulimit –a command. These values can be changed by the user; however, there must be a limit to how far a user can increase their own ulimits, and this is where the hard values come into play. A user cannot go above the hard limit value, and only the root user can change that. To give a user unlimited ulimit values, the root user specifies the new values as '-1'.

To see the soft ulimits, use: ulimit –a

To see the hard ulimits, use: ulimit -H

Let's now demonstrate how a ulimit can affect normal user processing. Below is the soft file limit for a user. Note that the fsize is the maximum size in total that a user can write in to a file. In the following example, this is currently set to 2097151 512 K blocks, about 1 GB.

$ ulimit -f

Now, if the user tries to create a 900 MB file, all should be fine because the user's ulimit setting for fsize allows that.

$ dd if=/dev/zero of=filename bs=1 count=0 seek=900M
0+0 records in.
0+0 records out.

Now, if we create a 2 GB file, it will be refused.

$ dd if=/dev/zero of=filename2 bs=1 count=0 seek=2G
dd: filename2: A file cannot be larger than the value set by ulimit.
dd: filename2: A file cannot be larger than the value set by ulimit.

By setting the fsize to around 3 GB ,the above 2 GB file can now be generated by the user:

# chuser fsize=6291453 dxtans
$ ulimit -f

Note in the above example, I did not go down the easy path and set the fsize to ulimited (-1); rather, I set it to a sensible value that was required for the processing to complete.

$ dd if=/dev/zero of=filename2 bs=1 count=0 seek=2G
0+0 records in.
0+0 records out.

Of course, this is all well and good where a user can view the ulimit setting, consider though an application account that is failing due to some ulimit issues. How can you tell what the ulimits are from a running process? Well, there is not any clean method available, and the only one I recall is using the dbx command, a source file debugger utility. Unfortunately, this has the side effect of killing the process after you exit dbx. First, obtain the process identification number (PID) of the required process, and then use dbx to interrogate it using the proc limit command.

# ps -ef |grep collector
  dxtans 2961626 2941074   0 13:04:07  pts/0  0:00 collector
# dbx -a 2961626
Waiting to attach to process 2961626 ...
Successfully attached to collector.
warning: Directory containing collector could not be determined.
Apply 'use' command to initialize source path.

Type 'help' for help.
reading symbolic information ...warning: no source compiled with -g

stopped in read at 0xd0398168
0xd0398168 (read+0x1a8) 80410014         lwz   r2,0x14(r1)
(dbx) proc rlimit
rlimit name:          rlimit_cur               rlimit_max       (units)
 RLIMIT_CPU:         (unlimited)             (unlimited)        sec
 RLIMIT_FSIZE:       (unlimited)             (unlimited)        bytes
 RLIMIT_DATA:          134217728             (unlimited)        bytes
 RLIMIT_STACK:          33554432             (unlimited)        bytes
 RLIMIT_CORE:        (unlimited)             (unlimited)        bytes
 RLIMIT_RSS:            33554432             (unlimited)        bytes
 RLIMIT_AS:          (unlimited)             (unlimited)        bytes
 RLIMIT_NOFILE:            65535             (unlimited)        descriptors
(dbx) quit

From the above output, we can see the current running ulimits of a process. However, when you exit dbx, the process will be killed. Of course, the process could be stopped cleanly first, before exiting dbx.

Restricting shell and FTP

When there is a need to implement a more restrictive shell environment, one possibility is to implement the restricted shell. This is simple enough, right? Select the restricted shell you want to use by making sure that it is in: /etc/security/login.cfg. Then, use the chuser command to change the account to the restricted shell required. The user is now restricted. That is only going to work with a novice user, and not for an experienced user. All they have to do is type in another SHELL like bash (assuming that it is installed) and they are no longer restricted. To fully put a user in a restrictive shell environment, point their PATH to a BIN directory located outside of the user's HOME directory where there are links to commands that the account can only run. That is the only sure way to lock a user down in a restrictive SHELL. To impose a chroot, FTP is an easy process (thanks to the IBM® AIX® /etc/ftpaccess.ctl file). First create the user and then assign the user as a puseronly in /etc/ftpaccess.ctl, using the following format. The change is dynamic and the user will be able to change out of their HOME directory:


There are other restrictive words that can put in the file, but for a basic chroot in their HOME directory, that will do it.

Enforcing disk quotas

One sensible method of controlling disk usage is to use disk quotas based on the limit parameters you set. This is a popular method in controlling the disk space that a user can use. Within my environment, we have a lot of machines and a lot of developers. So, if I did not enforce quotas, the HOME file system would be full on those development hosts most days. The amount of times you catch developers trying to hide database dumps in their HOME directory seems to be a normal practice. I find it beneficial also from a housekeeping point of view to use disk quota on log directories that the developers use, mainly because this is their second choice when trying to keep files on the system when they are about to breach their quota limit in their HOME directory.


Enforcing restriction on processes and the environment helps to keep your housekeeping to a minimal (there are no two ways about that). It is also a good standard to have across your development boxes, as it requires only less work on your part in clearing up files.



developerWorks: Sign in

Required fields are indicated with an asterisk (*).

Need an IBM ID?
Forgot your IBM ID?

Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.


All information submitted is secure.

Dig deeper into AIX and Unix on developerWorks

Zone=AIX and UNIX
ArticleTitle=Enforcing environmental limits