mirror of
git://git.gnu.org.ua/pam-modules.git
synced 2025-04-26 00:19:52 +03:00
pam_fshadow: new option skip-password
* pam_fshadow/pam_fshadow.c (pam_opt): New option skip-password. (_pam_parse,verify_user_acct,verify_user_pass): Fix log messages. (verify_user_pass): Skip password verification, if requested. (pam_sm_authenticate): Don't try to obtain password, if skip-password is given. Bugfix: even if password hash is given in passwd and verified successfully, verify the shadow file too, this time with password set to NULL, so that the actual account status is taken into account. * doc/pam-modules.texi: Document skip-password * doc/pam_fshadow.8in: Likewise.
This commit is contained in:
parent
1af3541706
commit
203524c85d
3 changed files with 66 additions and 18 deletions
|
@ -106,6 +106,7 @@ Authentication against an alternative shadow file.
|
|||
|
||||
* plain mode::
|
||||
* virtual domain mode::
|
||||
* disabling password checking::
|
||||
* summary of pam_fshadow options::
|
||||
|
||||
Authentication using regular expressions.
|
||||
|
@ -344,6 +345,7 @@ describe the plain mode.
|
|||
@menu
|
||||
* plain mode::
|
||||
* virtual domain mode::
|
||||
* disabling password checking::
|
||||
* summary of pam_fshadow options::
|
||||
@end menu
|
||||
|
||||
|
@ -489,6 +491,21 @@ user name was @samp{smith@@ftp}, then the module will look
|
|||
for the user name @samp{smith} in files
|
||||
@file{/etc/auth/ftp/passwd} and @file{/etc/auth/ftp/shadow}.
|
||||
|
||||
@node disabling password checking
|
||||
@section Disabling password checking
|
||||
|
||||
You can instruct @command{pam_fshadow} to skip password checking using
|
||||
the @code{skip-password} option. When given this option,
|
||||
the module will only check whether the user is listed in the password
|
||||
and/or shadow files, and whether the user's account in the latter is
|
||||
active and has not expired. This way @command{pam_fshadow} can
|
||||
be used as an auxiliary module in the stack, actual authentication being
|
||||
performed by one of the modules before it.
|
||||
|
||||
This option can be used both in plain and in virtual domain mode. The
|
||||
use of either file (but not both) can be disabled by the
|
||||
@code{nopasswd} and @code{noshadow} options.
|
||||
|
||||
@node summary of pam_fshadow options
|
||||
@section Summary of pam_fshadow options
|
||||
|
||||
|
@ -530,6 +547,11 @@ name and authentication domain.
|
|||
selects authentication domain, and group #2 selects user name.
|
||||
@xref{virtual domain mode, revert-index}.
|
||||
|
||||
@opsummary{skip-password}
|
||||
@item skip-password
|
||||
Skip password verification. Check only that the user name is listed
|
||||
in the password and/or shadow files. @xref{disabling password checking}.
|
||||
|
||||
@opsummary{sysconfdir}
|
||||
@item sysconfdir=@var{dir}
|
||||
Assume @var{dir} as the system configuration directory.
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
.\" This file is part of PAM-Modules -*- nroff -*-
|
||||
.\" Copyright (C) 2001-2021 Sergey Poznyakoff
|
||||
.\" Copyright (C) 2001-2022 Sergey Poznyakoff
|
||||
.\"
|
||||
.\" PAM-Modules is free software; you can redistribute it and/or modify
|
||||
.\" it under the terms of the GNU General Public License as published by
|
||||
|
@ -14,7 +14,7 @@
|
|||
.\" You should have received a copy of the GNU General Public License
|
||||
.\" along with PAM-Modules. If not, see <http://www.gnu.org/licenses/>.
|
||||
.so config.so
|
||||
.TH PAM_FSHADOW 8 "December 22, 2017" "PAM-MODULES" "Pam-Modules User Reference"
|
||||
.TH PAM_FSHADOW 8 "February 3, 2022" "PAM-MODULES" "Pam-Modules User Reference"
|
||||
.SH NAME
|
||||
pam_fshadow \- use alternative passwd and/or shadow files
|
||||
.SH SYNOPSIS
|
||||
|
@ -30,6 +30,7 @@ pam_fshadow \- use alternative passwd and/or shadow files
|
|||
[\fBnoshadow\fR]\
|
||||
[\fBregex=\fIEXPR\fR]\
|
||||
[\fBrevert\-index\fR]\
|
||||
[\fBskip\-password\fR]\
|
||||
[\fBsysconfdir=\fIDIR\fR]\
|
||||
[\fBuse_authtok\fR]\
|
||||
[\fBusername\-index=\fIN\fR]\
|
||||
|
@ -101,6 +102,12 @@ regex=(.*)@(.*)
|
|||
|
||||
This regular expression will match user names like \fBsmith@domain\fR.
|
||||
.TP
|
||||
.B skip\-password
|
||||
Disable password verification. With this flag, the module only checks
|
||||
whether the user is listed in the password and shadow files and
|
||||
whether the user's account has not expired. Use of either file
|
||||
can be disabled using \fBnopasswd\fR or \fBnoshadow\fR (but not both).
|
||||
.TP
|
||||
\fBusername\-index=\fIN\fR
|
||||
Use \fIN\fRth parenthesized group of the regular expression as the
|
||||
user name. Default is 1.
|
||||
|
@ -214,7 +221,7 @@ Sergey Poznyakoff <gray@gnu.org>
|
|||
.SH "BUG REPORTS"
|
||||
Report bugs to <bug\-pam\-modules@gnu.org.ua>.
|
||||
.SH COPYRIGHT
|
||||
Copyright \(co 2001-2014 Sergey Poznyakoff
|
||||
Copyright \(co 2001-2022 Sergey Poznyakoff
|
||||
.br
|
||||
.na
|
||||
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/* This file is part of pam-modules.
|
||||
* Copyright (C) 2001-2021 Sergey Poznyakoff
|
||||
* Copyright (C) 2001-2022 Sergey Poznyakoff
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
|
@ -101,6 +101,7 @@ fgetpwent(FILE *fp)
|
|||
#define CNTL_SHADOW 0x0040
|
||||
#define CNTL_REGEX 0x0080
|
||||
#define CNTL_REVERT_INDEX 0x0100
|
||||
#define CNTL_SKIP_PASSWORD 0x0200
|
||||
|
||||
static regex_t rexp;
|
||||
static char *sysconfdir = SYSCONFDIR;
|
||||
|
@ -140,6 +141,8 @@ struct pam_opt pam_opt[] = {
|
|||
{ .value = CNTL_REVERT_INDEX } },
|
||||
{ PAM_OPTSTR(username-index), pam_opt_long, &username_index },
|
||||
{ PAM_OPTSTR(domain-index), pam_opt_long, &domain_index },
|
||||
{ PAM_OPTSTR(skip-password), pam_opt_bool, &cntl_flags,
|
||||
{ .value = CNTL_SKIP_PASSWORD } },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -160,7 +163,7 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
|
|||
|
||||
if ((cntl_flags & (CNTL_PASSWD|CNTL_SHADOW)) == 0) {
|
||||
_pam_log(LOG_CRIT,
|
||||
"either passwd or shadow must be true");
|
||||
"at least one of passwd or shadow must be set");
|
||||
return PAM_AUTHINFO_UNAVAIL;
|
||||
}
|
||||
if (username_index <= 0) {
|
||||
|
@ -340,8 +343,13 @@ verify_user_acct(const char *confdir, const char *username, char **pwd)
|
|||
username, filename);
|
||||
retval = PAM_USER_UNKNOWN;
|
||||
} else {
|
||||
if (pw->pw_passwd && strlen(pw->pw_passwd) > 1)
|
||||
if (pw->pw_passwd && strlen(pw->pw_passwd) > 1) {
|
||||
if (debug_level && !(cntl_flags & CNTL_SKIP_PASSWORD)) {
|
||||
_pam_debug("user %s: password hash obtained from %s",
|
||||
username, filename);
|
||||
}
|
||||
*pwd = strdup(pw->pw_passwd);
|
||||
}
|
||||
retval = PAM_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
|
@ -364,12 +372,13 @@ verify_user_pass(const char *confdir, const char *username,
|
|||
int retval = PAM_AUTH_ERR;
|
||||
char *shadow = mkfilename(confdir, "shadow");
|
||||
|
||||
if (debug_level == 100)
|
||||
if (debug_level == 100 && password)
|
||||
_pam_debug("Verifying user `%s' with password `%s' in `%s'",
|
||||
username, password, shadow);
|
||||
else if (debug_level >= 10)
|
||||
_pam_debug("Verifying user `%s' in `%s'",
|
||||
username, password, shadow);
|
||||
_pam_debug("Verifying user `%s' in `%s'%s",
|
||||
username, shadow,
|
||||
password ? "" : " (password verification turned off)");
|
||||
|
||||
fp = fopen(shadow, "r");
|
||||
if (!fp) {
|
||||
|
@ -407,6 +416,9 @@ verify_user_pass(const char *confdir, const char *username,
|
|||
/* Account has expired */
|
||||
retval = PAM_ACCT_EXPIRED;
|
||||
#endif
|
||||
else if (password == NULL)
|
||||
/* No password verification is required */
|
||||
retval = PAM_SUCCESS;
|
||||
else if (strcmp(sp->sp_pwdp, crypt(password, sp->sp_pwdp)) == 0)
|
||||
retval = PAM_SUCCESS;
|
||||
else
|
||||
|
@ -532,21 +544,28 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
|
|||
return retval;
|
||||
|
||||
/* Get the password */
|
||||
if (_pam_get_password(pamh, &password, "Password:"))
|
||||
return PAM_SERVICE_ERR;
|
||||
if (cntl_flags & CNTL_SKIP_PASSWORD)
|
||||
password = NULL;
|
||||
else if ((retval = _pam_get_password(pamh, &password, "Password:")) != PAM_SUCCESS)
|
||||
return retval;
|
||||
|
||||
if (cntl_flags & CNTL_PASSWD)
|
||||
retval = verify_user_acct(confdir, username, &pwstr);
|
||||
else
|
||||
retval = PAM_SUCCESS;
|
||||
if (retval == PAM_SUCCESS) {
|
||||
if (pwstr) {
|
||||
if (strcmp(pwstr, crypt(password, pwstr)) == 0)
|
||||
retval = PAM_SUCCESS;
|
||||
else
|
||||
retval = PAM_AUTH_ERR;
|
||||
free(pwstr);
|
||||
} else if (cntl_flags & CNTL_SHADOW)
|
||||
if (password) {
|
||||
if (pwstr) {
|
||||
if (strcmp(pwstr, crypt(password, pwstr)) == 0) {
|
||||
password = NULL;
|
||||
retval = PAM_SUCCESS;
|
||||
} else
|
||||
retval = PAM_AUTH_ERR;
|
||||
free(pwstr);
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == PAM_SUCCESS && (cntl_flags & CNTL_SHADOW))
|
||||
retval = verify_user_pass(confdir, username, password);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue