aboutsummaryrefslogtreecommitdiff
path: root/pam_fshadow/pam_fshadow.c
diff options
context:
space:
mode:
Diffstat (limited to 'pam_fshadow/pam_fshadow.c')
-rw-r--r--pam_fshadow/pam_fshadow.c120
1 files changed, 79 insertions, 41 deletions
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
186 _pam_log(LOG_NOTICE, 198 && domain_index <= rexp.re_nsub)) {
187 "invalid regular expression `%s': " 199 if (username_index > rexp.re_nsub)
188 "must contain two reference groups", 200 _pam_log(LOG_NOTICE,
189 regex_str); 201 "not enough parenthesized groups"
202 " to satisfy username-index");
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/* --- authentication management functions (only) --- */ 456/* --- authentication management functions (only) --- */
440 457
458static int
459translate(pam_handle_t *pamh, char const *input,
460 char **ret_username, char **ret_confdir)
461{
462 size_t nmatch = (domain_index > username_index
463 ? domain_index : username_index) + 1;
464 regmatch_t *rmatch;
465 int rc;
466
467 rmatch = calloc(nmatch, sizeof(rmatch[0]));
468 if (!rmatch) {
469 _pam_log(LOG_ERR, "out of memory");
470 return PAM_SERVICE_ERR;
471 }
472
473 if (regexec(&rexp, input, nmatch, rmatch, 0) == 0) {
474 char *domain;
475
476 if ((rc = copy_backref(pamh, "DOMAIN", input, rmatch,
477 domain_index, &domain)) == PAM_SUCCESS
478 && ((rc = copy_backref(pamh, "USERNAME", input, rmatch,
479 username_index, ret_username))
480 == PAM_SUCCESS)) {
481 *ret_confdir = mkfilename(sysconfdir, domain);
482 pam_set_data(pamh, "CONFDIR",
483 (void *)*ret_confdir, gray_cleanup_string);
484 }
485 } else {
486 DEBUG(1,("user name `%s' does not match regular "
487 "expression `%s'",
488 input,
489 regex_str));
490 rc = PAM_AUTH_ERR;
491 }
492 free(rmatch);
493 return rc;
494}
495
441PAM_EXTERN int 496PAM_EXTERN int
442pam_sm_authenticate(pam_handle_t *pamh, int flags, 497pam_sm_authenticate(pam_handle_t *pamh, int flags,
443 int argc, const char **argv) 498 int argc, const char **argv)
444{ 499{
445 const char *username; 500 const char *input_username;
501 char *username;
446 char *password; 502 char *password;
447 int retval = PAM_AUTH_ERR; 503 int retval = PAM_AUTH_ERR;
448 int rc; 504 int rc;
@@ -455,8 +511,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
455 confdir = sysconfdir; 511 confdir = sysconfdir;
456 512
457 /* Get the username */ 513 /* Get the username */
458 retval = pam_get_user(pamh, &username, NULL); 514 retval = pam_get_user(pamh, &input_username, NULL);
459 if (retval != PAM_SUCCESS || !username) { 515 if (retval != PAM_SUCCESS || !input_username) {
460 DEBUG(1,("can not get the username")); 516 DEBUG(1,("can not get the username"));
461 if (cntl_flags & CNTL_REGEX) 517 if (cntl_flags & CNTL_REGEX)
462 regfree(&rexp); 518 regfree(&rexp);
@@ -464,39 +520,21 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags,
464 } 520 }
465 521
466 if (cntl_flags & CNTL_REGEX) { 522 if (cntl_flags & CNTL_REGEX) {
467 regmatch_t rmatch[3]; 523 retval = translate(pamh, input_username, &username, &confdir);
468 if (regexec(&rexp, username, 3, rmatch, 0) == 0) {
469 char *domain;
470
471 rc = copy_backref(pamh, "DOMAIN", username, rmatch,
472 domain_index, &domain);
473 if (rc != PAM_SUCCESS)
474 return rc;
475 rc = copy_backref(pamh, "USERNAME", username, rmatch,
476 username_index, (char **) &username);
477 if (rc != PAM_SUCCESS)
478 return rc;
479 confdir = mkfilename(sysconfdir, domain);
480 pam_set_data(pamh, "CONFDIR",
481 (void *)confdir, gray_cleanup_string);
482 } else {
483 DEBUG(1,("user name `%s' does not match regular "
484 "expression `%s'",
485 username,
486 regex_str));
487 }
488 regfree(&rexp); 524 regfree(&rexp);
525 } else {
526 retval = PAM_SUCCESS;
527 username = (char *) input_username;
528 confdir = sysconfdir;
489 } 529 }
530
531 if (retval != PAM_SUCCESS)
532 return retval;
490 533
491 /* Get the password */ 534 /* Get the password */
492 if (_pam_get_password(pamh, &password, "Password:")) 535 if (_pam_get_password(pamh, &password, "Password:"))
493 return PAM_SERVICE_ERR; 536 return PAM_SERVICE_ERR;
494 537
495 if (retval != PAM_SUCCESS) {
496 _pam_log(LOG_ERR, "Could not retrive user's password");
497 return -2;
498 }
499
500 if (cntl_flags & CNTL_PASSWD) 538 if (cntl_flags & CNTL_PASSWD)
501 retval = verify_user_acct(confdir, username, &pwstr); 539 retval = verify_user_acct(confdir, username, &pwstr);
502 else 540 else

Return to:

Send suggestions and report system problems to the System administrator.