NSLU2-Linux
view · edit · print · history

So, you've got Unslung installed and now you'd like to change the root password to something of your own choosing. Well, the /bin/unsling script from InstallUnslungFirmware will ask you for a new root password when you first unsling a disk. But what if you want to change the root password later, or change other passwords than root?

You change the password with the passwd utility, but when the NSLU2 reboots, it goes back to the default root passwd and you're left scratching your head wondering what went wrong.

Overview

The problem here is that the actual passwd file for the NSLU2 is kept in /share/hdd/conf/passwd and /usr/local/passwd. When the NSLU2 boots, whatever file is located at /etc/passwd is overwritten with a symlink to either /share/hdd/conf/passwd (when an unslung disk is attached) or /usr/local/passwd (when not unslung or no disk present).

When the passwd utility is used to change your password, /etc/passwd is overwritten with a good passwd file but not the others, and so the changes do not persist after a reboot. In order to change your password from the command line you need to do 2 things:

  1. run passwd to change the password and create a new /etc/passwd file
  2. copy the new file at /etc/passwd into the appropriate persistent file

To do this for a slug using an Unslung disk plugged into USB port 1, run these commands:

  1. passwd
  2. cp /etc/passwd /share/hdd/conf/passwd

To do this for a slug using an Unslung disk plugged into USB port 2, run these commands:

  1. passwd
  2. cp /etc/passwd /share/flash/conf/passwd

Scripts to simplify the job


Here's a little shell script to take care of all this for you.

 
#!/bin/sh
# 
# slugpasswd - change password on NSLU2 after an unslung disk is attached
#
# change password 
passwd $1
#
# copy to unslung disk in port 1
cp /etc/passwd /share/hdd/conf/passwd
#
# Optionally change the /usr/local copy (not recommended for inexperienced users)
cp /etc/passwd /usr/local/passwd
 

When you do this, be absolutely sure about 2 things:

  1. The passwd file is valid. An invalid file can lock you out of the slug.
  2. You are copying into the appropriate location. There are generally 3 disks to worry about, the internal flash, USB port 1, and USB port 2.

This procedure works in version 5.5-beta. If this stops working in later versions, it may be helpful to search for all locations of passwd:

 find / -name 'passwd'

To change the web admin password from the command prompt try htpasswd. http://www.acme.com/software/thttpd/htpasswd_man.html

Here is the command to find the .htpasswd files to work with.

 find / -name .htpasswd

Here is the command to edit the admin of a given file.

 htpasswd -c /dir/.htpasswd admin #where dir is the directory found with find

My firmware doesn't include htpasswd so i can't test it. A quick fix is to edit a known working file and copy its encrypted password or whole file, however the key changes so this might not work.


There are generally 3 disks to worry about

Too many files, not enough neurons for me to keep it straight...

Here is a more intelligent script. This one will:

  • Preserve the symbolic link
  • Update all known copies of the passwd file
  • Handle any number of arguments for the passwd command
  • Update all secondary files without running the passwd command. Useful if you edit /etc/passwd to change a shell.
  • Handle errors if the passwd command fails

To use, install as /opt/bin/spasswd (chmod +x, of course).

/opt/bin/spasswd --help will provide usage.

If someone who knows the current boot flow wants to resolve the open issue - re-generating the symlink based on the boot device if /etc/passwd starts out as a regular file - please do. (And let me know.)

This seems to work on V5.5-beta.

Read and obey the previous cautions, and enjoy.

--tlhackque

 
#!/bin/sh
#
# /bin/spasswd - manage /etc/passwd and its aliases
#
# tlhackque
#
# Parse command switches.  Musn't conflict with /usr/bin/passwd.
#
if [ "($1)" = '(--verbose)' ]; then
   VERBOSE=y
   shift
else
   VERBOSE=
fi
#
# Determine if /etc/passwd starts out as a symlink
#
if [ -L /etc/passwd ]; then
  INITIALPW=`ls -l /etc/passwd | sed -e 's|.*/etc/passwd -> \(/share/.*/conf/passwd\)$|\1|'`
  if [ "$VERBOSE" != '' ]; then echo "/etc/passwd -> $INITIALPW" ; fi
else
  INITIALPW=/etc/passwd
fi
#
if [ "($1)" != "(--refresh)" ]; then
  if [ "($1)" = "(--help)" ]; then
    cat <<EOF
Usage: $0 [--verbose] passwd_command_arguments
       $0 [--verbose] --refresh
       $0 --help

If --verbose is present, verbose output is produced for
reassurance (or debug).

The first format executes the /usr/bin/passwd command with
the specified arguments (if any).  If the command succeeds,
it then locates the other copies of the /etc/passwd file
and updates them by copying the new /etc/passwd file over
them.

The second format refreshes the copies, but does not
execute /usr/bin/passwd.  Use this after any manual
edits to /etc/passwd.  Be sure to use an editor that
preserves symbolic links, or edit the target!

The third format displays this message.

Issues:
  Perhaps /etc/passwd should be set to the appropriate
  symbolic link if it starts out as a regular file.
EOF
    exit
  else
    /usr/bin/passwd $* || exit
   # /etc/passwd has been updated, and probably is not a symlink.
  fi
fi
#
# /etc/passwd may be a symlink to the real file
#
if [ -L /etc/passwd ]; then
  ACTIVEPW=`ls -l /etc/passwd | sed -e 's|.*/etc/passwd -> \(/share/.*/conf/passwd\)$|\1|'`
else
  ACTIVEPW=/etc/passwd
fi
#
if [ "$VERBOSE" != '' ]; then echo "Updated $ACTIVEPW" ; fi
#
# Used when booting from disk 1
#
if [ -n "`mount | grep /share/hdd/conf`" ]; then
  if [ "$ACTIVEPW" != "/share/hdd/conf/passwd" ]; then
     cp /etc/passwd /share/hdd/conf/passwd
     if [ "$VERBOSE" != '' ]; then echo "Updated /share/hdd/conf/passwd" ; fi
  fi
fi
# Used when booting from disk 2
if [ -n "`mount | grep /share/flash/conf`" ]; then
  if [ "$ACTIVEPW" != "/share/flash/conf/passwd" ]; then
     cp /etc/passwd /share/flash/conf/passwd
     if [ "$VERBOSE" != '' ]; then echo "Updated /share/flash/conf/passwd" ; fi
  fi
fi
# Used when no disk present -- cat used because flash FS
# doesn't like cp
if [ "$ACTIVEPW" != "/usr/local/passwd" ]; then
   cat /etc/passwd >/usr/local/passwd
   if [ "$VERBOSE" != '' ]; then echo "Updated /usr/local/passwd" ; fi
fi
#
# If the initial /etc/passwd was a symlink, restore it.
if [ "$INITIALPW" != "/etc/passwd" ]; then
   ln -sf $INITIALPW /etc/passwd
   if [ "$VERBOSE" != '' ]; then echo "Re-linked /etc/passwd -> $INITIALPW" ; fi
fi
# EOF
 

Question: Is the script above still true for the Unslung 6.8?

for me it works, mike 22.06.06


An alternative:

The boot sequence for 6.8 is rc.sysinit -> rc.1, which calls rc.reset_usrgrpshare.

rc.reset_usrgrpshare calls /usr/sbin/reset_ugs which replaces the /etc/passwd file with one from memory.

rc.reset_usrgrpshare is:

 
#!/bin/sh

if ( [ -f /unslung/rc.reset_usrgrpshare ] && . /unslung/rc.reset_usrgrpshare ) ; then return 0 ; fi

/usr/sbin/reset_ugs;
 

The problem can be fixed by:

1. Copy /etc/passwd to /opt/etc/passwd (which will not be overwritten). Remember to do this after any changes to passwords or users or 'cp /etc/passwd /opt/etc/passwd' can be added to rc.reboot and rc.halt.

2. Create /unslung/rc.reset_usrgrpshare like so:

 
#!/bin/sh

/usr/sbin/reset_ugs

cp /opt/etc/passwd /etc/passwd;
 

Alternative: edit the persistent passwd file directly

There's more than one way to skin a cat. You can also access the NSLU2 disk from Linux, and edit the file in the "conf" partition named /passwd. This is the file which on the NSLU2 becomes /share/hdd/conf/passwd. It is a normal Linux /etc/passwd format file. The simplest operation is to copy the encrypted password from one user's entry to another.

On firmware version V2.3R63-uNSLUng-6.10-beta...

...it seems that changes in /share/flash/data/etc/passwd are persistent. (If I'm not totally mixing off something right now.) -GreenBear?, 26.08.2008 On my machine, this is a link to /share/flash/conf/passwd -dbh 2009-02-09

Page last modified on February 10, 2009, at 02:00 AM