Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Is there a non-root shell command that can tell me if a user's account is disabled or not?

Please note that I make a distinction between LOCKING and DISABLED:

  • LOCKING is where you prepend ! or * or !! to the password field of the /etc/passwd or /etc/shadow file. Password locking can be done (at a shell prompt) via password -l username (as root) to lock the account of username, and the use of the option -u will unlock it.
  • DISABLING an account is done by setting the expiration time of the user account to some point in the past. This can be done with chage -E 0 username, which sets the expiration date to 0 days after the Unix epoch. Setting it to -1 will disable the use of the expiration date.

For my situation, the use of locking is not sufficient because a user might still be able to login, e.g. using ssh authentication tokens, and processes under that user can still spawn other processes. Thus, we have accounts that are enabled or disabled, not just locked. What I'm looking for is a way to check the enable/disable status of an account via a shell command, for use in a custom Java process. The Java process can parse the output or make use of the exit code, and it can execute complicated statements such as those including pipes between commands.

This is intended for use on a Red Hat Enterprise 5.4 system.

This question was previously asked on SuperUser.

share|improve this question
    
this is not possible as you describe, because: the information is described only in shadow, and shadow can only be read by root. Any program needing password hashes or account expiration must be SUID (if you're using local accounts stored in shadow, as you say.) –  Michael Lowman Aug 11 '11 at 19:22
    
Are you sure that the expiration info resides only in /etc/shadow ? If you can elaborate on that in an answer, I'll mark it as the accepted one - thanks. We already have a plan for using a SUID script, it's just more work because we also have SELinux in strict enforcing mode for which we would need to modify policy. –  weiji Aug 12 '11 at 19:57
    
Just a thought, there may be a ton of reasons why this is a bad idea. Could you set the path of the users shell to /sbin/nologin in the password file when you disable the account? Even if they can log in with a token, wouldn't that keep them from running any commands? The Java process could read the passwd file and check if the shell is disabled. –  codewaggle Oct 2 '12 at 0:37
add comment

4 Answers

up vote 2 down vote accepted

From comment:
This is not possible as you describe, because: the information is described only in shadow, and shadow can only be read by root. Any program needing password hashes or account expiration must be SUID (if you're using local accounts stored in shadow, as you say.)

Added information:
I initially used chage(1) as source.

Note

The chage program requires a shadow password file to be available.

I have now updated my information to be more precise, confirming things.

First of all, I checked chage's source code just to be sure. It seems that it does indeed need access to the shadow file and store the information nowhere else. Second, you can use PAM to allow use of chage's root features. (check_perms at chage.c:523)

And as others have said, anything else used as the backend for shadow (namely, anything in nsswitch.conf for it except files and db) has its own ways of working with things.

In short: when using files as the backend, password aging information is indeed stored there and only there. If you still want to use files backend you should write a program and make it SUID, since the system's all or nothing. You can query just your user, or you can query and set everybody. On the plus side, writing something in C to do what you want would only be a few lines of code. You could basically copy three functions out of chage's source and add a new main.

share|improve this answer
    
Many thanks for the thorough and in-depth research. A+++ answer, would buy again. –  weiji Aug 12 '11 at 21:25
add comment

I'm not sure if there's an easy way to check. I doubt as a regular user you'd have r access to the passwd file (Not the shadow one), so you couldn't really easily sed/awk/grep for the ! field.

What you could do is design a very specific script, make it non rwx to non-root and then create a sudo entry specifically for that command. You could even make it passwordless. Ideally you wouldn't be accepting any input so it would also be harder to 'break' the script. I suppose it comes down to how paranoid you want to be/who's going to have access to it.

share|improve this answer
    
No. On RHEL5 (and the handful of other Linux distros that I have personally used), the /etc/passwd file is readable by a regular user. The question is not about access to this file, or a way to parse for the lock-flag in the password field. I am looking for account expiration info, which can be provided by chage -l <username> but that specific use of chage is restricted to root. I note the difference between locking and disabling in my question body - please read it carefully. –  weiji Aug 11 '11 at 22:36
add comment

There is no non-root command, but a root command. It is passwd -S <username>. Which does output the following:

Display account status information. The status information consists of 7 fields. The first field is the user's login name. The second field indicates if the user account has a locked password (L), has no password (NP), or has a usable password (P). The third field gives the date of the last password change. The next four fields are the minimum age, maximum age, warning period, and inactivity period for the password. These ages are expressed in days.

So the best would be to call a script like

#!/bin/sh
passwd -S $1

and allow that to be called with sudo and no password from within the Java program.

Beware: The above script is vulnerable for code injection, so you have to secure it for your purpose.

share|improve this answer
    
Unfortunately, no. First of all, passwd is not a root command - it can be used by non-root users. Second, the -S option does not show the expiration date of the account. –  weiji Aug 11 '11 at 22:28
    
Yes it 'can' be used as non-root. But you only get information about others as being root. –  mailq Aug 11 '11 at 22:32
    
I misread your answer - it seemed to read that passwd itself is only available to root. It still doesn't give me what I'm looking for. –  weiji Aug 11 '11 at 22:44
add comment

One way would be to move your account information to LDAP or SQL. Then use PAM modules for integrating those with your server. Your Java application can easily access LDAP or SQL directly.

For bonus points this approach is more scalable and manageable if you have many servers with same user base. /etc/passwd also starts to suffer performance-wise if you have thousands of user accounts or more.

share|improve this answer
    
uhhm... I don't think so. Our Java process runs under a normal user account, so accessing any other user's account information will still potentially need root access. It's not clear in your answer if or how I can get the expiration info without root privs. Also, moving account information to "LDAP or SQL" is not an option for us, and we don't need to scale to thousands of user accounts. This RHEL installation is going on a laptop, with only 1 local user at a time, and accounts are not synchronized. –  weiji Aug 12 '11 at 20:07
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.