28

I want to assign 2 passwords to a single account. What I want to know is 1) is this possible, and 2) what are the security implications of this?

The reason I want to do this is because I'm currently busy with some local testing, and I thought it would be convenient in some specific situations. After some research I found something called PAM, but I'm struggling to find information on how installation / configuration works.

I'm running Ubuntu 12.04.

1
  • 2
    I would probably just setup sudo to allow user1 to run commands as user2. (sudo isn't just for running commands as root; it can run commands as any user.)
    – cjm
    Commented Sep 15, 2013 at 2:06

5 Answers 5

22

Yes, although quite uncommon, this is definitely doable.

Instead of trying to implement it yourself as the default /etc/password /etc/shadow based authentication method has no provision for such a configuration, the simpler way is to delegate authentication to a back-end that already supports multiple password for a user.

A well known one is LDAP which userPassword attribute is multivalued according to RFC4519:

An example of a need for multiple values in the 'userPassword' attribute is an environment where every month the user is expected to use a different password generated by some automated system. During transitional periods, like the last and first day of the periods, it may be necessary to allow two passwords for the two consecutive periods to be valid in the system.

Despite this RFC, you'll likely need to change the password policy configuration on most directory server implementations for this setting to be actually accepted.

On the Linux side, nothing forbids to do it (here an account named testuser was given both pass1 and pass2 as userPassword attribute values):

$ uname -a
Linux lx-vb 3.8.0-19-generic #29-Ubuntu SMP Wed Apr 17 18:16:28 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux
$ grep VERSION /etc/os-release
VERSION="13.04, Raring Ringtail"
$ grep "^passwd" /etc/nsswitch.conf 
passwd: files ldap
$ ldapsearch -LLL -h localhost -p 1389 -D "cn=directory manager" -w xxxxxxxx "uid=testuser" userPassword
dn: uid=testuser,ou=People,dc=example,dc=com
userPassword:: e1NTSEF9b2JWYXFDcjhNQmNJVXZXVHMzbE40SFlReStldC9XNFZ0NU4yRmc9PQ==
userPassword:: e1NTSEF9eDlnRGZ5b0NhKzNROTIzOTFha1NiR2VTMFJabjNKSWYyNkN3cUE9PQ==
$ grep testuser /etc/passwd
$ getent passwd testuser
testuser:*:12345:12345:ldap test user:/home/testuser:/bin/sh
$ sshpass -p pass1 ssh testuser@localhost id
uid=12345(testuser) gid=12345 groups=12345
$ sshpass -p pass2 ssh testuser@localhost id
uid=12345(testuser) gid=12345 groups=12345
$ sshpass -p pass3 ssh testuser@localhost id
Permission denied, please try again.

Here are some technical and security related implications of that kind of configuration:

  • the user account will obviously be more vulnerable to attacks although what really matters here is the quality and protection of the passwords more than their numbers.
  • most utilities assume the user has a single password so won't allow a user to individually update one of the passwords. Password change will then likely result in a single password attribute for the user.
  • if the goal is to allow multiple people to share the same account using each one their own password, there is no mechanism to identify who actually log in based on the password used.
3
  • 1
    Can you please elaborate on why this has no security implications? My first impression was that it would increase the chances of an account being compromised, especially if one password is significantly weaker than the other.
    – Joseph R.
    Commented Sep 15, 2013 at 13:12
  • 1
    @JosephR. You are correct. I just updated my reply after implementing what I suggested and experiencing with it.
    – jlliagre
    Commented Sep 15, 2013 at 22:51
  • 1
    Excellent answer, works like a charm now. Thanks :) Commented Sep 16, 2013 at 6:19
8

I just attempted to create 2 entries for a user in the /etc/shadow file and it did not work. Which ever entry was first was the password entry that was used.

Example

Created a test user.

$ useradd -d /home/newuser newuser

Set the password to "super123":

$ passwd newuser

Manually edit the /etc/shadow file and made a second entry:

newuser:$6$....password #1...:15963:0:99999:7:::
newuser:$6$....password #2...:15963:0:99999:7:::

Then attempt to login with the account using the 2 passwords.

su - newuser

The first entry in /etc/shadow is what get's used, the entry in the second position never works, if you flip these like so:

newuser:$6$....password #2...:15963:0:99999:7:::
newuser:$6$....password #1...:15963:0:99999:7:::

Then the second password works and the first one doesn't.

Use sudo

This approach is a total hack, I would just use sudo, it's partially why sudo exists.

You can add this entry to your sudoers file (/etc/sudoers) which would allow user joe permission to do anything as you:

joe ALL=(yourusername) ALL
1
  • I actually forgot that sudo can do that.. +1 Commented Sep 15, 2013 at 18:08
4

If you can do this, you probably shouldn't.

PAM configuration is somewhat complex and there is one truism about authentication mechanisms: there are a finite set of correct configurations but an infinite set of insecure configurations. This makes it almost a certainty that if you try to change things and don't know precisely what you are doing you'll screw things up.

If the choice is between security and "convenient in some specific situations", opt for the former.

1
  • +1 for "security over convenience" (which I fully agree with), but I am the type of person who wants to test everything even if only for the experience, so not 100% the answer I'm looking for. Commented Sep 15, 2013 at 18:04
2

You can set two different usernames, each with their password, for the same account. Run vipw to edit /etc/passwd manually, duplicate the existing line for the account you're interested in and change the username (and if you like the Gecos field, home directory and shell). Run vipw -s and duplicate the line for that user in /etc/shadow. Log in under the new username and run passwd to change the password for the new username. You now have two different usernames, with different passwords, for the same account (the user ID is what determines the account).

This is probably not a good idea. Depending on what you're trying to do, other approaches may be more appropriate:

  • Create another account and share files by committing and checking out from version control.
  • Create another account, create a group that both user accounts belong to, and give group write access to files that you want to share.
  • Create another account and give the first account the right to run commands as that account with sudo:

    user1 ALL = (user2) ALL
    
  • Create an SSH key for the account that only allows running one specific command.
1
  • would you mind copying this over to herehttp://askubuntu.com/questions/567139/2-password-1-account-login ?
    – Rinzwind
    Commented Dec 30, 2014 at 19:38
0

You can write a small PAM module to accept several different (hardcoded) passwords for an account.

Here's an example source code for such a module:

// Compile with:
//   gcc -fPIC -shared -o pam_multipass.so pam_multipass.c -lpam -lssl -lcrypto
// Install into /lib/security/ (or other location, depending on your distribution):
//   sudo install --mode=0755 --owner=root --group=root pam_multipass.so /lib/security/pam_multipass.so

#define _GNU_SOURCE
#include <stdio.h>
#include <security/pam_modules.h>
#include <security/pam_ext.h>
#include <string.h>
#include <openssl/sha.h>

#define USERNAME "username"

#define PASSWORD_HASH_1 "xxxxxxxx"
#define PASSWORD_HASH_2 "xxxxxxxx"

PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) {
  const char *username;
  char *password;
  unsigned char result[SHA256_DIGEST_LENGTH];
  char hexstring[65];

  // Get the username
  pam_get_user(pamh, &username, NULL);
  if (strcmp(username, USERNAME) != 0) {
    return PAM_IGNORE; // Not the user we're interested in
  }

  // Prompt for password
  if (pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &password, "%s", "Password: ") != PAM_SUCCESS) {
    fprintf(stderr, "pam_multipass pam_prompt failed\n");
    return PAM_IGNORE;
  }
  if (pam_set_item(pamh, PAM_AUTHTOK, password) != PAM_SUCCESS) {
    fprintf(stderr, "pam_multipass failed to set PAM_AUTHTOK\n");
  }

  SHA256((unsigned char *) password, strlen(password), result);
  for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
    sprintf(hexstring + (i * 2), "%02x", result[i]);
  }

  // Compare with expected hash
  if (
      strcmp(hexstring, PASSWORD_HASH_1) == 0
      || strcmp(hexstring, PASSWORD_HASH_2) == 0
  ) {
    return PAM_SUCCESS;
  } else {
    return PAM_IGNORE; // Allow other modules to authenticate
  }
}

PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }
PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_IGNORE; }

You'll need to add the module to the PAM configuration, and that might be tricky. I'll give an example for Arch Linux distribution, adapt to other distributions as needed:

# in /etc/pam.d/system-auth
auth       required                    pam_faillock.so      preauth
auth       [success=3 default=ignore]  pam_multipass.so  # <--- our module
auth       [success=2 default=ignore]  pam_unix.so          try_first_pass nullok
-auth      [success=1 default=ignore]  pam_systemd_home.so
auth       [default=die]               pam_faillock.so      authfail
auth       optional                    pam_permit.so
auth       required                    pam_env.so
auth       required                    pam_faillock.so      authsucc

But in any case, be extra careful - don't do any such thing if you don't thoroughly understand everything that you are doing (e.g., why is there success=3 directive in PAM config?).

1
  • Always wondered what a useful, basic PAM module would lool like. This is awesome. I also think this is more what I would have wanted years back, so I guess the accepted answer goes to you XD Commented Oct 16, 2023 at 5:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .