Adventures in Red Hat Enterprise Linux, CentOS, Fedora, OpenBSD and other open source solutions.

An example of using "chroot" to reset a password of a linux machine

I tried to explain what "chrooting" is to a group of starting Linux gurus. It seemed rather difficult to explain. So, maybe an illustrated article will explain what chroot is.

From chroot's manpage:

chroot - run command or interactive shell with special root directory

And in my own words:

chroot starts a process in a directory which looks like the root directory to that process.

Here is an example of how chroot can be used to reset a root password on an existing system. (Even works when the bootloader (grub) has a password set.)

  1. Insert a linux boot or install CD/DVD and make the computer boot from that cd.
  2. When the CD boots and starts the installer, hit [CTRL]+[ALT]+[F2] to go to a shell.
  3. Now that you have a shell available, you must mount the / (maybe /usr too) directory. Mostly you don't know what directory was the / directory, so you will end up mounting an unmounting a few times. mkdir /mnt/a && mount /dev/sda5 /mnt/a && mount /dev/sda3 /mnt/a/usr
  4. When you have the required mountpoints mounted, execute a chroot, like this: chroot /mnt/a /bin/sh
  5. Now you can execute passwd, which is actually /mnt/a/usr/bin/passwd. The password will be updated in /etc/shadow, which is actually /mnt/a/etc/shadow

Here is a screenshot to illustrate the procedure: (click to enlarge)

Why does "reboot" work as a user on Fedora Core?

If you are a normal (non-root) user on Fedora Core 9, you are able to reboot a machine without the usage of a password. Reboot initiates all kind of scripts that should normally be run as root, while "reboot" does not have a set user id bit set:

$ which reboot
$ ls -l /usr/bin/reboot
lrwxrwxrwx 1 root root 13 2008-11-11 22:18 /usr/bin/reboot -> consolehelper
$ ls -l /usr/bin/consolehelper
-rwxr-xr-x 1 root root 3904 2008-08-03 09:10 /usr/bin/consolehelper
$ file /usr/bin/consolehelper
/usr/bin/consolehelper: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.9, stripped

From the man page of consolehelper I find:

consolehelper  is  a  tool  that makes it easy for console users to run system programs, doing authentication via PAM (which can be set  up  to trust all console users or to ask for a password at the system administrator’s discretion).

And in /etc/pam.d/reboot there is:

auth       sufficient
auth       required
#auth       include system-auth
account    required

And from the manpage of  is designed to give users at the physical console (virtual terminals and local xdm-managed X sessions by default, but that is configurable)  capabilities  that they would not otherwise have, and to take those capabilities away when the are no longer logged  in  at  the console.

So; reboot is permitted by non-root users when they are logged into the console. To test this, login to a machine, try "reboot":

reboot: Need to be root

"Set User ID bit" demostration

The "set user id"-bit (or setuid-bit) is a potentially dangerous permission type. Wrong usage of setuid can result in unauthorized access to your system.

What it means

When a setuid bit is set to an executable, the script will be executed as if it was executed by the owner of the file. So for example this script has a setuid bit set:

$ ls -l
-rwsr-xr-x 1 root wheel 200 Nov 5 10:47

This script may be executable by anybody. When executed by the user "robert" for example, it will inherit permissions as if it was executed by root.

Imagine that this script contains the command "reboot"; in that case anybody would be able to reboot the machine.

How you can set it

Very easy:

# chmod 4755

# chmod u+s

What you can do with it

Here is a small demonstration, first showing that a user can't write to /etc/passwd.

$ echo "foo bar" >> /etc/passwd
-bash: /etc/passwd: Permission denied

Now set the setuid bit:
# chmod u+s /bin/echo

With the setuid bit on, the user is able to write to /etc/passwd:
$ echo "foo bar" >> /etc/passwd

See the dangerous situation we have just created? Undo it by executing # chmod u-s /bin/echo.

How to detect (and resolve) it

# find / -perm -4000

Please notice that there are many files on a system that have setuid bits, like:

  • /bin/mount - because a user needs to be able to mount a cdrom or floppy.
  • /bin/ping
  • /usr/bin/crontab

Cygwin is not as scary as it looks

Most people on the windows platform know Cygwin. ("Cygwin is a Linux-like environment for Windows.") As I never use Windows, I feared programs like these, but it turns out cygwin is quite usable. It's even possible to run shell scripts that normally run on my Mac OS X machine.

Download the installer, select all packages you want. (Don't worry, all "generic" tools (ls, cd, grep, awk, ps, bash) are installed by default.) I added "openssh", "netcat", "xterm" and some others. Dependencies will be resolved automatically. The installer downloads everything. You can run the installer again to add extra packages.

You end up with a "Cygwin" icon. Double click it to start your terminal. It's not really a terminal, but looks quite like it.

Some things are strange or missing, like "top" that's missing, permissions (ls -al) look strange, just as the directory structure. But; take some distance from these details and conclude that you have "bash" running on your windows machine!

The command comm is more difficult that you might think

Have you ever used the command comm? It's a Linux command used to compare two (sorted) files. Comm produces three columns of output:
1: Lines only in file 1.
2: Lines only in file 2.
3: Lines in bothe files.

You can surpress columns by using options like "-1", "-2", "-12" and so on.

Imagine file 1 contains:

$ cat file1

And file 2 contains:

$ cat file2

Than these options (left) would produce this output (right):

Option output explanation
-1 ACD Show lines only in file 2 and in both files
-2 ABC Show lines only in file 1 and in both files
-3 BD Show lines in file 1 and in file 2, but not in both files
-12 AC Show lines in both files
-13 D Show lines only in file 2
-23 B Show lines only in file 1
-123 (no output) Surppress all columns

Linux permission system explained

When you are new to Linux or don't use Linux on a daily basis, finding out how file permissions work can be challenging. Here is an as short as possible guide, which can be applied on UNIX, Linux, Mac OS X, FreeBSD, OpenBSD, and other UNIX-like operating systems. We'll call those systems *nix in this guide.

*nix splits permissions in thee groups for files and directories:

  1. Owner This is the person/account that owns the file.
  2. Group This refers to a set of users. 1 or more persons/accounts can be member of a group.
  3. World If you'r not the Owner, and not part of a Group for a specific file or directory, you automatically match World. Normally the permissions given to World, are restricted.

Besides ownership of files and directories, certain permissions can be given as well:

  1. Read The entity (Owner, Group or World) is allowed to read a file.
  2. Write The entity is allowed to write a file, or to create files in the directory for which these permissions are set.
  3. Execute The entity is allowed to execute the file (scripts or binaries) or to change into this directory.

These permissions are set using chmod. (Change Mode.) Ownership of file is altered with chown. (Change Owner)

Chmod wants to know what permissions you give to a file or directory. This value is built up on four fields.

The zeroth field represents the special bits. (Set User id, Set Group id and Stikcy bit, see below.) Most users will not set this bit, which makes it "0" by default, which means: "No special permissions set."
The first field represents the permissions you give to the Owner.
The second field represents the permissions you give to the Group.
The third fiels represents the permissions you give to the World.

Chmod uses numerical arguments to set permissions, to illustrate it a bit: chmod 750 would change permissions for the file

Read permissions equals a value of 4.
Write permissios equals a value of 2.
Execute permissions equals a value of 1.

Add the numbers representing the permissions you'd like to give to a Owner, Group or World.

So here is a list of common permissions:

  • 750 - The Owner may read, write and execute. The Group may read and execute. (but not write) The world may not do anything with this file.
  • 755 - Same as above, but the world may now also read and execute the file.
  • 700 - The Owner may do everything, the Group and the world may not do anything.
  • 640 - The Owner may read and write, the Group may read and the world may not do anything.
  • 644 - Same as above, but the world may now also read the file.
  • 600 - The Owner may read and write, the rest may not do anything.

Some "weird" permissions, mostly because they are broken or very rare:

  • 000 - Nobody may do anything with this file. Effectively archive the file. Maybe removing the file would be more appropriate.
  • 007 - The Owner and Group can't do anything, but the World can. I can't think of a situation where this would apply.
  • 100 and 300 - The Owner may execute but not read, so the execute will not work.
  • 200 - The owner may write, but not read. The only situation I could imagine is a logfile where some application may write to, but is not allowed to read the file.

There are some special permissions you can give, these permissions go into the zeroth field. You'd use chmod like this to set no special permissions: chmod 0750

  1. Sticky bit A value of 1. This bit is commonly set to directories and means that you may only remove file in such a directory that are owned by you. The filesystem /tmp is commonly set with that bit; everyone can write there, but you can only remove/rename files that are owned by yourself.
  2. Set Group id A value of 2. The file is executed as the Group of the file. Some groups have quite some premissions. Imagine /bin/rm (to remove files and directories) having a Set Group id bit, all users in the Group of /bin/rm may remove a whole lot of files. When you are using Set User id or Set Group id bits, you should be very sure you know what you are doing.
  3. Set User id A value of 4. If this permission is given, the program is executed as the Owner of the file. Could be dangerous; think of a PHP script that tries to reboot a machine...

So 4750 would mean the file may be executed by the owner and the group, and will be executed as the owner.

Imagine a script would have 4775 permissions and would be owned by root:users; a user could edit the script, and the world could execute it with roots permission!

Just to remind you once more; Set Group or User id bits are dangerous, know what you are doing when using them!

How to enable tftp server on Mac OS X

When you would like to use TFTP on your Mac OS X machine, take these simple steps:

  1. Change /System/Library/LaunchDaemons/tftp.plist Quite simple; remove two lines <key>Disabled</key> and <true/>. Besides that, I added the -l option with <string>-l</string>, but that's optional.
  2. Load tftp.plist into launchd The command launchdctl load /System/Library/LaunchDaemons/tftp.plist will do that.
  3. Monitor /var/log/system.log With the command tail -f /var/log/system.log

Now place the required files in /private/tftpboot and you are done!

Change ssh configuration when the "Location" changes on Mac OS X

Have you ever used the "Location" facility in Mac OS X? It changes network settings for you when you work from different locations, like "work", "home", "mobile" or any other setting. As far as I can tell it's designed to change:

  • IP, netmask, gateway
  • Used interfaces (airport, ethernet, etc)
  • Proxy server

What's missing here is SSH settings. You configure your ssh-client in ~/.ssh/config manually. In my case I can login a machine from home directly, but when I am somewhere else, I need to use a step-stone.

That would mean I'd have to change ~/.ssh/config every time I am on a different location! Here is a solution to the problem, inspired by an article about Location based scripts.

  1. Create a new Location in Mac OS X Click on the Apple logo in the left corner, Location - Network Preferences - Edit Locations - The + symbol and so on.
  2. Copy/create ssh configurations, call them ~/.ssh.$PROFILE and replace $PROFILE by the name you came up with for you profile names. I use "~/.ssh/config.Automatic" and "~/.ssh/config.Mobile".
  3. Add a few lines to /~.locationchanger These lines actually link ~/.ssh/config to the right ssh configuration.
    location=$(scselect 2>&1|grep ' \* ' | awk '{print $NF}' | sed 's/(//g;s/)//g')
    if [ -f ~/.ssh/config.$location ] ; then
    rm ~/.ssh/config
    ln -s ~/.ssh/config.$location ~/.ssh/config
  4. Make the ~/.locationchanger executable Use chmod 750 ~/.locationchanger to do that.
  5. Create a file ~/Library/LaunchAgents/LocationChanger.plist The content should be like this:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
    <plist version="1.0">
  6. Load that LocationChanger into launchd. Use launchctl load ~/Library/LaunchAgents/LocationChanger.plist to do this, or reboot.

From now on the script ~/.locationchanger will be started when changing Location.

Some items that might be changed when you switch locations are using a stepstone to ssh to machines or using corkscrew to puch through http proxies.

This tool uses scselect, an apple tool that confiures or prints locations.

SCSELECT(8)               BSD System Manager's Manual              SCSELECT(8)

     scselect -- Select system configuration "location"

     scselect [-n] [new-location-name]

     scselect provides access to the system configuration sets, commonly
     referred to as "locations".  When invoked with no arguments, scselect
     displays the names and associated identifiers for each defined "location"
     and indicates which is currently active.  scselect also allows the user
     to select or change the active "location" by specifying its name or iden-
     tifier.  Changing the "location" causes an immediate system re-configura-
     tion, unless the -n option is supplied.

     At present, the majority of preferences associated with a "location"
     relate to the system's network configuration.

     The command line options are as follows:

     -n  Delay changing the system's "location" until the next system boot (or
         the next time that the system configuration preferences are changed).

         If not specified, a list of the available "location" names and asso-
         ciated identifiers will be reported on standard output.  If speci-
         fied, this argument is matched with the "location" names and identi-
         fiers and the matching set is activated.


     The scselect command appeared in Mac OS X Public Beta.

Mac OS X                       November 4, 2003                       Mac OS X

Calculating a prime number with a shell script

For experimental purposes I tried to write a shell script that calculates a whole range of prime numbers. The script seems to be working, but is not very efficient. While writing this script I found a regular expression that does the same thing, only a couple of hundred times faster.

Here is that experimental shell script to calculate a prime number:


throughnoother() {
# A function to calculate if the only argument given is not dividable through any other number.
# Set the status to no. No means, not a prime number. When every test is successful, change
# the status to yes.
# num starts at 1, and is increased by one each time.
# This for loop consists of numbers up to half the value of the given argument.
for divider in $(while [ $num -lt $(($1/2)) ] ; do num=$(($num+1)) ; echo $num ; done) ; do
  # This is not the test to divide through its own value, so skip that.
  if [ $1 != $divider ] ; then
   # This tests to see if the rounded calculation can be reversed and gives the same result.
   if [ $((($1/$divider)*$divider)) = $1 ] ; then
# End by printing the status.
echo $status

# Start at 2.

while [ 1 ] ; do
# This first if test, test if the number is dividable through 1 and if it's dividable through itself.
  if [ $(($number/1)) = $number -a $(($number/$number)) = 1 ] ; then
   if [ $(throughnoother $number) != "yes" ] ; then
    # If all tests are succesful, then it must be a prime number, print it!
    echo "$number"
# Now increase the number to be tested by one.

How to burn an ISO file on a DVD in Mac OS X using Disk Utility

Because I alway forget how this exactly works, here is how to get and ISO image burned onto a DVD in Mac OS X. You will be using the application Disk Utility as it is installed by default on Mac OS X.

  1. Download the .ISO file to your computer. Use the desktop to find it back easily, but any other place will work just fine!
  2. Open Disk Utility. You can find this application in Utilities.
  3. Drag the .ISO file onto the left column (white) of Disk Utility. This tells the Disk Utility to do something with that ISO file.
  4. Highlight the image in the Disk Utility.
  5. Click Burn from the toolbar on top. Another screen will pop up, hit Burn to start burning.

Syndicate content