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) viapassword -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.
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.
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.
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.
There is no non-root command, but a root command. It is
passwd -S <username>
. Which does output the following:So the best would be to call a script like
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.
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.