linuxubuntupasswdlinux-capabilities

/usr/bin/passwd and the CAP_CHOWN capability


I was experimenting with Linux Capabilities, and I noticed that for the passwd program to work without being Set-UID root, it needs to have the CAP_CHOWN capability (in addition to some others). Logically, why would it need to have CAP_CHOWN at all?

Incidentally, passwd gives me a "token manipulation error" if I remove the capability.

Edit: I'm using Ubuntu 11.04 without SELinux. I'm trying to get passwd to work without being Set-UID root.


Solution

  • The cap_chown is not required for the passwd itself. It is only needed to change the /etc/shadow file associated with the userID. The /etc/shadow file is set so that it cannot be read by just anyone.

    /etc/shadow is only accessible to root. So when /etc/passwd finishes it's authentication module and is ready to write a new (encoded) password, it will create a token. Which is accessed by the Linux-PAM service, which will chown it to root and write it into /etc/shadow.

    Edit:

    passwd uses the files /etc/.pwd.lock, /etc/shadow , /etc/nshadow. Since passwd reads and writes from /etc directory, w permissions are requried by it. Note that, /etc/shadow is never written by passwd. passwd actually writes to /etc/nshadow and renames /etc/nshadow to /etc/shadow.

    open('/etc/nshadow',O_WRONLY|O_CREAT)=fd1
    open('/etc/shadow', O_RDONLY)=fd2
    fchown(fd1, uid=root, gid=shadow)
    chmod /etc/shadow to : rw by owner and r by group
    read(fd2)
    write(fd1)
    rename("/etc/nshadow", "/etc/shadow")
    

    Furthermore, I confirmed the existence of /etc/nshadow using this C program. FYI,

    #include<stdio.h>
    #include<unistd.h>
    int main()
    {
    while(1)
    if (access("/etc/nshadow",F_OK)!=-1){
        printf("Exists\n");
        break;
        }
    return 0;
    }