13

Disclaimer: This question is not to solve the problem of changing root password while SELinux is active because there are a lot of guides to solve that already. This is more of how SELinux does that internally.

I'm a recent user of SELinux but lately I've been more in touch with it. There was a moment when someone asked me how I could reset root password in case of forgetting it.

So I booted my CentOS, edited grub entry to something like

linux16 <kernel_location> root=/dev/mapper/centos-root rw init=/bin/bash

I ran passwd and afterwards ran sync and forced reboot. After reboot, logging in with the new password was rejected as well as with the old of course.

Rebooted again and passed the kernel the parameter to disable SELinux (selinux=0). Tried logging in with the new password and it worked. Afterwards I forced a fs auto relabel (via the file .autorelabel) and with SELinux active it was now possible to log in.

My question is: why does happen? Why does relabeling affect log in when there was merely a change of password and not of users or objects?

Thank you for your attention.

TL;DR: Usual root password reset doesn't work in SELinux. Why?

Edit: This was tested on a virtual machine running CentOS7 with KVM as hypervisor.

Alexey Vazhnov
  • 549
  • 5
  • 14
Jorge Heleno
  • 230
  • 3
  • 10
  • 1
    Are you sure it doesn't work? Try it again. It probably will work fine. I suspect that you simply had wrong file contexts on some files, causing all logins to fail. Thus the autorelabel was what really fixed the problem. – Michael Hampton Oct 18 '18 at 14:37
  • @MichaelHampton I just retraced all my steps doing it again and couldn't log in again with SELinux active. After disabling it I could log in without a problem. Correct me if I'm wrong but changing a password shouldn't change file contexts right? – Jorge Heleno Oct 18 '18 at 14:42
  • 1
    No it shouldn't. You seem to have discovered something strange and unexpected. – Michael Hampton Oct 18 '18 at 14:43

1 Answers1

19

I was able to duplicate this issue in a freshly installed CentOS 7.5 system.

Here is what is happening:

When you boot with init=/bin/bash there are two issues you may run into:

  • The root filesystem may be mounted readonly. In this case passwd will complain of an Authentication token manipulation error.

    This is pretty obvious: If the filesystem is not mounted read-write, it is not possible to write to it.

  • The SELinux policy may not be loaded. In this case passwd will successfully change the password, but you will have the problem described in the original question above: no one will be able to log in.

    Password hashes are stored in the /etc/shadow file. This file normally has the SELinux type shadow_t. However, changing the file while no SELinux policy is loaded causes the SELinux type to be removed from the file, leaving it as unlabeled_t. Thus, services which try to read the file to authenticate logins are no longer able to read it.

To change the root password on RHEL/CentOS 7, you therefore need to follow this process:

  1. Add init=/bin/bash to the end of the kernel command line in grub, as you previously did.
  2. At the bash prompt, load the SELinux policy with /usr/sbin/load_policy -i.
  3. Mount the root filesystem read-write with mount -o remount,rw /.
  4. Now change the password, and it will succeed. passwd root
  5. Remount the filesystem readonly to commit changes and have a clean filesystem on next boot with mount -o remount,ro /.
  6. Exit the shell or restart the system with exec /sbin/init 6.

Now you can log in with the changed root password.

A longer explanation of this procedure is available from Red Hat (subscription required).

Michael Hampton
  • 244,070
  • 43
  • 506
  • 972
  • The problem was on the policies which weren't loaded. Why don't they get loaded? SELinux should operate at kernel level so init system shouldn't be required. – Jorge Heleno Oct 18 '18 at 15:30
  • 4
    @JorgeHeleno SELinux is indeed on or off by default when the kernel starts, but the userland is responsible for deciding which policies are loaded. The kernel could not decide this, because some installations may want different policies (e.g. targeted, strict, mls). This happens early in the boot process, but you bypass that when you run `init=/bin/bash`. – Michael Hampton Oct 18 '18 at 15:35
  • 1
    if a policy is not loaded why the `passwd` "appears to succeed"? – Andrew Savinykh Oct 18 '18 at 18:31
  • and if it didn't succeed, why did logging in with the old password still fail? – Lightness Races in Orbit Oct 18 '18 at 18:39
  • I was forced to log in just to upvote this. – user9517 Oct 18 '18 at 20:02
  • The `passwd` command runs without a problem and the password was altered. We can check that the password was altered if we pass the parameter `selinux=0` to the kernel through grub. With this the login with the new password is successful. The problem lies in the policies. Since loading policies is done in userspace, SELInux's policies weren't loaded when `passwd` was ran therefore it didn't give it a new context and when SELinux loads (on reboot) with the policies activated, the file doesn't contain the policies. – Jorge Heleno Oct 18 '18 at 20:12
  • 2
    @Jorge Helen: Your explain is nearly complete. The point is the files altered by `passwd` namely `/etc/passwd` and `/etc/shadow`. If running `passwd` without loaded policy, it does not run in the proper selinux context, and the altered files end up with a different selinux context. When booting with selinux enabled, and policies active the password check fails because of inappropriate file context, and not because of `wrong password` error. Forcing selinux to relable filecontexts by touching `/.autorelabel` can also fix that issue when changing passwords without loaded policy. – hargut Oct 19 '18 at 05:50