aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-12-22 15:22:14 +0200
committerSergey Poznyakoff <gray@gnu.org.ua>2017-12-22 15:25:58 +0200
commit55620228a87786860e5eeabbab146a835e9830cf (patch)
tree3692518804feccff77aae50cf1ea3614ccb639be
parentfc8bf4028f468848ab00efb41e6c2a76be2174c9 (diff)
downloadpam-modules-55620228a87786860e5eeabbab146a835e9830cf.tar.gz
pam-modules-55620228a87786860e5eeabbab146a835e9830cf.tar.bz2
pam_fshadow: allow the user to use arbitrary group numbers for username and domain parts.
New options username-index and domain-index are used to indicate indices of the parenthesized groups used to extract the user and the domain name. The default corresponds to 'user-index=1 domain-index=1'. Additionally, change the behavior in case if the user name doesn't match the regexp. Previous versions would fall back to plain authentication in this case. New behavior is to reject access. * pam_fshadow/pam_fshadow.c (pam_opt): New options username-index and domain-index. (pam_sm_authenticate): Move username splitting into a separate function. * doc/pam_fshadow.8in: Document the new options.
-rw-r--r--doc/pam_fshadow.8in37
-rw-r--r--pam_fshadow/pam_fshadow.c118
2 files changed, 101 insertions, 54 deletions
diff --git a/doc/pam_fshadow.8in b/doc/pam_fshadow.8in
index de4e471..261e0a8 100644
--- a/doc/pam_fshadow.8in
+++ b/doc/pam_fshadow.8in
@@ -1,5 +1,5 @@
1.\" This file is part of PAM-Modules -*- nroff -*- 1.\" This file is part of PAM-Modules -*- nroff -*-
2.\" Copyright (C) 2001-2015 Sergey Poznyakoff 2.\" Copyright (C) 2001-2017 Sergey Poznyakoff
3.\" 3.\"
4.\" PAM-Modules is free software; you can redistribute it and/or modify 4.\" PAM-Modules is free software; you can redistribute it and/or modify
5.\" it under the terms of the GNU General Public License as published by 5.\" it under the terms of the GNU General Public License as published by
@@ -14,14 +14,17 @@
14.\" You should have received a copy of the GNU General Public License 14.\" You should have received a copy of the GNU General Public License
15.\" along with PAM-Modules. If not, see <http://www.gnu.org/licenses/>. 15.\" along with PAM-Modules. If not, see <http://www.gnu.org/licenses/>.
16.so config.so 16.so config.so
17.TH PAM_FSHADOW 8 "March 30, 2014" "PAM-MODULES" "Pam-Modules User Reference" 17.TH PAM_FSHADOW 8 "December 22, 2017" "PAM-MODULES" "Pam-Modules User Reference"
18.SH NAME 18.SH NAME
19pam_fshadow \- use alternative passwd and/or shadow files 19pam_fshadow \- use alternative passwd and/or shadow files
20.SH SYNOPSIS 20.SH SYNOPSIS
21.nh 21.nh
22.na 22.na
23\fBpam_fshadow\fR\ 23\fBpam_fshadow\fR\
24 [\fBaudit\fR]\
25 [\fBdebug\fR[\fB=\fINUMBER\fR]]\
24 [\fBbasic\fR|\fBextended\fR]\ 26 [\fBbasic\fR|\fBextended\fR]\
27 [\fBdomain\-index=\fIN\fR]\
25 [\fBignore\-case\fR|\fBicase\fR|\fBcase\fR]\ 28 [\fBignore\-case\fR|\fBicase\fR|\fBcase\fR]\
26 [\fBnopasswd\fR]\ 29 [\fBnopasswd\fR]\
27 [\fBnoshadow\fR]\ 30 [\fBnoshadow\fR]\
@@ -29,9 +32,8 @@ pam_fshadow \- use alternative passwd and/or shadow files
29 [\fBrevert\-index\fR]\ 32 [\fBrevert\-index\fR]\
30 [\fBsysconfdir=\fIDIR\fR]\ 33 [\fBsysconfdir=\fIDIR\fR]\
31 [\fBuse_authtok\fR]\ 34 [\fBuse_authtok\fR]\
32 [\fBdebug\fR[\fB=\fINUMBER\fR]]\ 35 [\fBusername\-index=\fIN\fR]\
33 [\fBwaitdebug\fR]\ 36 [\fBwaitdebug\fR]
34 [\fBaudit\fR]
35.ad 37.ad
36.hy 38.hy
37.SH DESCRIPTION 39.SH DESCRIPTION
@@ -54,7 +56,7 @@ provided to disable reading of either file. E.g. if \fBnoshadow\fR is
54given, the module will expect all authentication information to be 56given, the module will expect all authentication information to be
55stored in the \fBpasswd\fR file. 57stored in the \fBpasswd\fR file.
56.PP 58.PP
57The \fBvirtual domain\fR mode select the \fBpasswd\fR,\fBshadow\fR 59The \fBvirtual domain\fR mode selects the \fBpasswd\fR,\fBshadow\fR
58pair to use depending on the user name. To that effect, the user name 60pair to use depending on the user name. To that effect, the user name
59is first split into the \fBlocal\fR and \fBauthentication domain\fR 61is first split into the \fBlocal\fR and \fBauthentication domain\fR
60parts using a regular expression supplied with the \fBregex\fR option. 62parts using a regular expression supplied with the \fBregex\fR option.
@@ -62,8 +64,7 @@ The configuration directory name is then constructed by concatenating the
62system configuration directory, a directory separator character (\fB/\fR), 64system configuration directory, a directory separator character (\fB/\fR),
63and the name of the authentication domain. The authentication then 65and the name of the authentication domain. The authentication then
64proceeds as described above for the plain mode. If the supplied user name 66proceeds as described above for the plain mode. If the supplied user name
65does not match the regular expression, \fBpam_fshadow\fR falls back to 67does not match the regular expression, \fBpam_fshadow\fR refuses access.
66the plain mode.
67.SH OPTIONS 68.SH OPTIONS
68.TP 69.TP
69\fBbasic\fR 70\fBbasic\fR
@@ -86,12 +87,12 @@ Use only \fBpasswd\fR file for authentication.
86.TP 87.TP
87\fBregex=\fIEXPR\fR 88\fBregex=\fIEXPR\fR
88Defines a regular expression for splitting user name into the proper 89Defines a regular expression for splitting user name into the proper
89name and authentication domain. The expression must contain two 90name and authentication domain. The expression must contain at least two
90parentesized groups. If it matches, the group 1 will be used to 91parentesized groups. If it matches, the group 1 will be used to
91extract local user name and the group 2 will select the authentication 92extract local user name and the group 2 will select the authentication
92domain. The \fBrevert\-index\fR option changes this behavior, causing 93domain. These default group indices can be changed using the
93group 1 to be used for authentication domain and group 2 for user 94\fBusername\-index\fR and \fBdomain\-index\fR options. Additionally the
94name. For example: 95\fBrevert\-index\fR option swaps the meaning of the two indices. For example:
95.RS 96.RS
96.EX 97.EX
97regex=(.*)@(.*) 98regex=(.*)@(.*)
@@ -100,9 +101,17 @@ regex=(.*)@(.*)
100 101
101This regular expression will match user names like \fBsmith@domain\fR. 102This regular expression will match user names like \fBsmith@domain\fR.
102.TP 103.TP
104\fBusername\-index=\fIN\fR
105Use \fIN\fRth parenthesized group of the regular expression as the
106user name. Default is 1.
107.TP
108\fBdomain\-index=\fIN\fR
109Use \fIN\fRth parenthesized group of the regular expression as the
110group name. Default is 2.
111.TP
103\fBrevert\-index\fR 112\fBrevert\-index\fR
104Use group #2 from the regular expression as the user name and group #1 113Swap indices of the username and domain part parenthesized groups in
105as the authentication domain. 114the regexp.
106.TP 115.TP
107\fBsysconfdir=\fIDIR\fR 116\fBsysconfdir=\fIDIR\fR
108Use \fIDIR\fR as the system configuration directory, instead of the 117Use \fIDIR\fR as the system configuration directory, instead of the
diff --git a/pam_fshadow/pam_fshadow.c b/pam_fshadow/pam_fshadow.c
index 058dd44..3dd07f5 100644
--- a/pam_fshadow/pam_fshadow.c
+++ b/pam_fshadow/pam_fshadow.c
@@ -103,15 +103,15 @@ fgetpwent(FILE *fp)
103#define CNTL_REGEX 0x0080 103#define CNTL_REGEX 0x0080
104#define CNTL_REVERT_INDEX 0x0100 104#define CNTL_REVERT_INDEX 0x0100
105 105
106char *sysconfdir = SYSCONFDIR; 106static regex_t rexp;
107static char *sysconfdir = SYSCONFDIR;
107static int cntl_flags = CNTL_PASSWD|CNTL_SHADOW; 108static int cntl_flags = CNTL_PASSWD|CNTL_SHADOW;
108static long debug_level = 0; 109static long debug_level = 0;
109 110
110static regex_t rexp;
111static const char *regex_str = NULL; 111static const char *regex_str = NULL;
112static int regex_flags = REG_EXTENDED; 112static int regex_flags = REG_EXTENDED;
113static int username_index = 1; 113static long username_index = 1;
114static int domain_index = 2; 114static long domain_index = 2;
115 115
116struct pam_opt pam_opt[] = { 116struct pam_opt pam_opt[] = {
117 { PAM_OPTSTR(debug), pam_opt_long, &debug_level }, 117 { PAM_OPTSTR(debug), pam_opt_long, &debug_level },
@@ -139,6 +139,8 @@ struct pam_opt pam_opt[] = {
139 { .value = CNTL_SHADOW } }, 139 { .value = CNTL_SHADOW } },
140 { PAM_OPTSTR(revert-index), pam_opt_bool, &cntl_flags, 140 { PAM_OPTSTR(revert-index), pam_opt_bool, &cntl_flags,
141 { .value = CNTL_REVERT_INDEX } }, 141 { .value = CNTL_REVERT_INDEX } },
142 { PAM_OPTSTR(username-index), pam_opt_long, &username_index },
143 { PAM_OPTSTR(domain-index), pam_opt_long, &domain_index },
142 { NULL } 144 { NULL }
143}; 145};
144 146
@@ -162,13 +164,23 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
162 "either passwd or shadow must be true"); 164 "either passwd or shadow must be true");
163 return PAM_AUTHINFO_UNAVAIL; 165 return PAM_AUTHINFO_UNAVAIL;
164 } 166 }
167 if (username_index <= 0) {
168 _pam_log(LOG_CRIT, "username-index out of range");
169 return PAM_AUTHINFO_UNAVAIL;
170 }
171 if (domain_index <= 0) {
172 _pam_log(LOG_CRIT, "domain-index out of range");
173 return PAM_AUTHINFO_UNAVAIL;
174 }
175
165 if (cntl_flags & CNTL_REVERT_INDEX) { 176 if (cntl_flags & CNTL_REVERT_INDEX) {
166 username_index = 2; 177 long t = username_index;
167 domain_index = 1; 178 username_index = domain_index;
179 domain_index = t;
168 } 180 }
169 if (regex_str) { 181 if (regex_str) {
170 int rc; 182 int rc;
171 if (rc = regcomp(&rexp, regex_str, regex_flags)) { 183 if ((rc = regcomp(&rexp, regex_str, regex_flags))) {
172 size_t s = regerror(rc, &rexp, NULL, 0); 184 size_t s = regerror(rc, &rexp, NULL, 0);
173 char *buf = malloc (s); 185 char *buf = malloc (s);
174 if (buf) { 186 if (buf) {
@@ -182,11 +194,16 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv)
182 "cannot compile regex `%s'", 194 "cannot compile regex `%s'",
183 regex_str); 195 regex_str);
184 retval = PAM_AUTHINFO_UNAVAIL; 196 retval = PAM_AUTHINFO_UNAVAIL;
185 } else if (rexp.re_nsub != 2) { 197 } else if (!(username_index <= rexp.re_nsub
198 && domain_index <= rexp.re_nsub)) {
199 if (username_index > rexp.re_nsub)
186 _pam_log(LOG_NOTICE, 200 _pam_log(LOG_NOTICE,
187 "invalid regular expression `%s': " 201 "not enough parenthesized groups"
188 "must contain two reference groups", 202 " to satisfy username-index");
189 regex_str); 203 if (domain_index > rexp.re_nsub)
204 _pam_log(LOG_NOTICE,
205 "not enough parenthesized groups"
206 " to satisfy domain-index");
190 regfree(&rexp); 207 regfree(&rexp);
191 retval = PAM_AUTHINFO_UNAVAIL; 208 retval = PAM_AUTHINFO_UNAVAIL;
192 } else 209 } else
@@ -438,11 +455,50 @@ copy_backref (pam_handle_t *pamh, const char *name,
438 455
439