Actually, first_valid_uid
only affects Dovecot's userdb lookup in passwd database and does not impact the passdb lookup. After delving into the source files, it becomes clear that the validity check takes place in the passwd_iterate_want_pw
function located in the file core/src/auth/userdb-passwd.c
:
static bool passwd_iterate_want_pw(struct passwd *pw, const struct auth_settings *set) {
/* Skip entries not in the valid UID range.
They're users for daemons and such. */
if (pw->pw_uid < (uid_t)set->first_valid_uid)
return FALSE;
if (pw->pw_uid > (uid_t)set->last_valid_uid && set->last_valid_uid != 0)
return FALSE;
if (pw->pw_gid < (gid_t)set->first_valid_gid)
return FALSE;
if (pw->pw_gid > (gid_t)set->last_valid_gid && set->last_valid_gid != 0)
return FALSE;
return TRUE;
}
If the function returns FALSE, the userdb lookup will skip that user, resulting in an error stating that the user is not found.
However, during the passdb lookup, a separate database is used to verify the username and password. Taking the default driver pam
as an example, its configuration file is located at /etc/pam.d/dovecot
, and lookup is performed in /etc/shadow
. The passdb lookup does not involve checking the validity of the username with the passwd database for userdb.
When the auth_debug = yes
setting is enabled in Dovecot's configuration file, here is an example of logs generated during an smtpd authentication:
1111-11-11T11:11:41.122920+00:00 myserver dovecot: auth: Debug: client in: AUTH#0114#011plain#011service=smtp#011nologin#011lip=127.0.0.1#011rip=127.0.0.1.87#011secured
1111-11-11T11:11:41.123831+00:00 myserver dovecot: auth: Debug: client passdb out: CONT#0114#011
1111-11-11T11:11:43.185585+00:00 myserver dovecot: auth: Debug: client in: CONT<hidden>
1111-11-11T11:11:43.185703+00:00 myserver dovecot: auth: Debug: pam(root,127.0.0.1.87): Performing passdb lookup
1111-11-11T11:11:43.194570+00:00 myserver dovecot: auth-worker(37592): Debug: Loading modules from directory: /usr/lib/dovecot/modules/auth
1111-11-11T11:11:43.195187+00:00 myserver dovecot: auth-worker(37592): Debug: Module loaded: /usr/lib/dovecot/modules/auth/lib20_auth_var_expand_crypt.so
1111-11-11T11:11:43.195807+00:00 myserver dovecot: auth-worker(37592): Debug: conn unix:auth-worker (pid=37547,uid=107): Server accepted connection (fd=13)
1111-11-11T11:11:43.196014+00:00 myserver dovecot: auth-worker(37592): Debug: conn unix:auth-worker (pid=37547,uid=107): Sending version handshake
1111-11-11T11:11:43.196326+00:00 myserver dovecot: auth-worker(37592): Debug: conn unix:auth-worker (pid=37547,uid=107): auth-worker<1>: Handling PASSV request
1111-11-11T11:11:43.196575+00:00 myserver dovecot: auth-worker(37592): Debug: conn unix:auth-worker (pid=37547,uid=107): auth-worker<1>: pam(root,127.0.0.1.87): Performing passdb lookup
1111-11-11T11:11:43.196757+00:00 myserver dovecot: auth-worker(37592): Debug: conn unix:auth-worker (pid=37547,uid=107): auth-worker<1>: pam(root,127.0.0.1.87): lookup service=dovecot
1111-11-11T11:11:43.199784+00:00 myserver dovecot: auth-worker(37592): Debug: conn unix:auth-worker (pid=37547,uid=107): auth-worker<1>: pam(root,127.0.0.1.87): #1/1 style=1 msg=Password:
1111-11-11T11:11:45.306854+00:00 myserver dovecot: auth: Debug: pam(root,127.0.0.1.87): Finished passdb lookup
As you can see, only the pam
module is called throughout the process, and there is no module to determine the validity of the user like the passwd
module. Consequently, the root
user can pass the SMTPD authentication as long as the password is correct and can send emails without any issues, although they won't be able to receive emails.
Considering the security vulnerabilities that enabling password login for the root user brings, it is advisable to run the command passwd -l root
to disable the password for root
. This command sets an impossible value for the root
user's password in the /etc/shadow
file. Consequently, no matter what password is attempted for root
in SASL, the pam
module will return an error Authentication failure (Password mismatch?)
, thus preventing root
from logging in via SASL.