1

Environment:

  OS: FreeBSD 12.1-Release-p10
  Sudo: 1.9.5p2
  Samba: 4.13.1_1

We've recently migrated to an Active Directory backend for DNS, DHCP, and in-house SSO support. I have SSH logins working well, using PAM to authenticate via the Samba/Winbindd setup. I want to control who can use sudo (just as root for now) via AD group memberships.

To that end, I created a new group in AD called "Unix Admins" that I would like sudo to check membership of, just like it does for local users and the wheel group. To that end I simply duplicated the existing wheel entry and have two group check lines as follows:

%wheel ALL=(ALL) ALL
%Unix\ Admins ALL=(ALL) ALL  

When an AD user who is not in either wheel or the new group logs in and tries to use sudo, they get the normal error about not being in the sudoers file, as expected. When they are in the AD group but not wheel, they are prompted for their password, and if they enter their password correctly the command executes as expected.

However, when they enter the wrong password, they are shown an error message that is a little cryptic given the situation, and then the command executes anyway as if they entered the correct password.

The error happens as follows:

% sudo ls
Password:
When trying to update a password, this return status indicates that the value provided as the current password is not correct.
<<ls output here>>

Edit: Edited for clarity.

Edit2: /etc/pam.d & /usr/local/etc/pam.d relevant contents

/usr/local/etc/pam.d/sudo

#
# $FreeBSD: branches/2021Q1/security/sudo/files/pam.conf 340872 2014-01-24 00:14:07Z mat $
#
# PAM configuration for the "sudo" service
#

# auth
auth            include         system

# account
account         include         system

# session
# XXX: pam_lastlog (used in system) causes users to appear as though
# they are no longer logged in in system logs.
session         required        pam_permit.so

# password
password        include         system

/etc/pam.d/system

#
# $FreeBSD: releng/12.1/lib/libpam/pam.d/system 197769 2009-10-05 09:28:54Z des $
#
# System-wide defaults
#

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
#auth           sufficient      pam_krb5.so             no_warn try_first_pass
#auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            sufficient      pam_unix.so             no_warn try_first_pass nullok
auth            sufficient      pam_winbind.so          try_first_pass

# account
#account        required        pam_krb5.so
account         required        pam_login_access.so
account         required        pam_unix.so

# session
#session        optional        pam_ssh.so              want_agent
session         required        pam_lastlog.so          no_fail

# password
#password       sufficient      pam_krb5.so             no_warn try_first_pass
password        required        pam_unix.so             no_warn try_first_pass
2
  • FreeBSD uses PAM doesn't it? Please post the contents of /etc/pam.d/sudo and any files that it includes by reference – roaima Feb 3 at 14:09
  • Done deal @roaima sorry for not putting them in the original message. The sudo PAM file is straight from the factory, the system file was modified to include pam_winbind, and to change the pam_unix module from required to sufficient. – alzee Feb 3 at 18:15
3

Here is your problem, "the system file was modified to include pam_winbind, and to change the pam_unix module from required to sufficient".

It would be well worth taking the time to read chapter 4.1 of the Linux PAM Administrators' Guide (yes, I know you're on FreeBSD), so that you can understand the detail of what I explain here.

When you had pam_unix set to required, it immediately returned success or failure depending on the validity of the password. When you changed it to sufficient it only returned success but otherwise continued on. There was now no failure mode.

Your auth stack can now return success or the default value, which happens to be success. To fix the problem, add a deny as the last stack entry for auth

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
auth            sufficient      pam_unix.so             no_warn try_first_pass nullok
auth            sufficient      pam_winbind.so          try_first_pass
auth            required        pam_warn.so
auth            required        pam_deny.so

Comment the pam_warn entry if you don't want PAM to log authentication failures.


Useful keywords for PAM stacks

  • required - failure will ultimately lead to the stack returning failure, but only after the remaining modules have been executed
  • requisite - failure will be returned immediately
  • sufficient - success will be returned immediately, unless a failure from required is already pending
9
  • That makes a ton of sense. I had no idea that the default would be to succeed rather than fail in the event that none of the modules resulted in success. – alzee Feb 4 at 2:41
  • Had a chance to investigate this today, and this is not the whole story unfortunately. While the man page says that processing stops at "sufficient" if it succeeds that doesn't seem to actually be the case, as adding a pam_deny after the two sufficient entries as you indicated causes all logins to fail, nevermind sudo.. – alzee Feb 5 at 16:47
  • @alzee I'll set up some tests locally too (Linux not FreeBSD) – roaima Feb 5 at 16:50
  • Cool. Here's the documentation from the FreeBSD pam.d man page regarding "sufficient" which indicates to me it shouldn't need the following pam_deny... <<sufficient>> If this module succeeds, the chain is broken and the result is success. If it fails, the rest of the chain still runs, but the final result will be failure unless a later module succeeds. – alzee Feb 5 at 16:55
  • 1
    I thought I'd come back and post my own answer, and let you know with an update. The issue was the two OPIE modules in my original question. They (well at least one of them) succeed even when the user hasn't set an OPIE password, causing the AUTH section to succeed even when all the passwords are wrong and the other modules are set to "sufficient." Just removing them fixed the issue -- and the default is to fail, not succeed, as the FreeBSD documentation indicates. – alzee Feb 12 at 0:12
0

The PAM modules in FreeBSD do not work like the ones in Linux as we had thought, and do in fact function as documented.

The problem lied in the preceeding modules in the auth section, regarding the OPIE system. Those modules are active by default and always succeed for users who do not initialize OPIE in their accounts -- which honestly, is basically everyone. That resulted in a passing auth subsection even when all "normal" auth modules returned failure, if those modules were set to "sufficient" or "optional".

The solution was to remove the lines referencing the two OPIE modules.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.