6

On older Debian machines one could issue something like:

echo '<username>:*'|chpasswd -e

in order to change the password field of the user (<username>) to *.

Now I am aware of

passwd -d <username> && passwd -l <username>

to achieve a similar effect and set the password field to !. However, on some newer vanilla Ubuntu configurations (in particular 10.04 LTS) this leads to the user not being able to log into the machine anymore (for example via SSH and key) - with: Your account has expired; please contact your system administrator. - even though passwd(1) "warns" that this is possible.

Now that's exactly what I want to achieve, though. Manually changing the field in the /etc/shadow file from ! to * fixes the issue, but there seems to be no scriptable way to achieve the same without directly fiddling with the shadow file (e.g. with sed). chpasswd -e used to be a convenient alternative, but that has been obviously removed.

So what I am looking for is either a variation of passwd -l that lets me choose the token that gets written into the file or any other kind of replacement for the exact functionality that chpasswd -e offered.

NB: * is already used for system accounts alright, and there seems to be a semantic difference to PAM or whatever between ! and * in the password field.

Also note: on Debian 5 and 6 chpasswd -e works. So the functionality must have gotten stripped deliberately in Ubuntu. I tested Ubuntu 9.10, 10.04 (they don't have it), 11.04 and 11.10 have chpasswd -e.

0xC0000022L
  • 5,656
  • 6
  • 52
  • 91
  • Your last note is a bit confusing, are you indicating that Ubuntu {9.10, 11.04, 11.10} have `chpasswd -e` and {10.04} doesn't? – Huckle Mar 15 '12 at 01:43
  • 1
    11.04 and 11.10 have it, 9.10 and 10.04 don't. – 0xC0000022L Mar 15 '12 at 12:32
  • IMHO, `sed` it until the next LTS server release comes out since it seems that 11.04+ now have it. 12.04 isn't too far off. – Huckle Mar 15 '12 at 23:09

1 Answers1

2

Use a simple script like this one I just wrote:

#!/bin/bash

USER=$1
if [[ -z "$USER" ]]; then
  echo "From which user should I clear the password?"
  read USER
fi
if chpasswd -e -h > /dev/null 2>&1; then
  echo "$USER:*"|chpasswd -e
else
  passwd -d $USER
  cp /etc/shadow /etc/shadow.old
  USEROLD=$USER::
  USERNEW=$USER:*:
  sed -i "s/$USEROLD/$USERNEW/g" /etc/shadow.old
  cp /etc/shadow.old /etc/shadow
fi

The use of the script is at own risk.

Marco Ceppi
  • 47,783
  • 30
  • 172
  • 197
  • +1 for the effort, though I wrote that I want to avoid any fiddling with the user database itself. I'm also going to accept for now, but may change this later if someone comes up with a clever alternative :) – 0xC0000022L Mar 29 '12 at 02:30
  • @Marco: you realize that `#!/usr/bin/env bash` is *much* more portable than `/bin/bash`, right? ... there was a reason I exchanged it. It's "best practice", basically :) – 0xC0000022L May 09 '12 at 14:54
  • @STATUS_ACCESS_DENIED You realize that this is Ubuntu, and as such bash is in the same place. Also, `env` is in different places on different distributions, so you really haven't solved much :) – Marco Ceppi May 09 '12 at 15:41
  • @Marco: unlike `bash`, `env` has been in the same location on various Linux distros, all BSDs, MacOS X, AIX, Solaris in various versions each. While `bash` on some systems is not `/bin` but `/local/bin` or `/usr/bin`. Yes, I realize it's Ubuntu, but that doesn't void a best practice :) – 0xC0000022L May 09 '12 at 16:19