diff options
Diffstat (limited to 'pam_fshadow/pam_fshadow.c')
-rw-r--r-- | pam_fshadow/pam_fshadow.c | 120 |
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 | ||
106 | char *sysconfdir = SYSCONFDIR; | 106 | static regex_t rexp; |
107 | static char *sysconfdir = SYSCONFDIR; | ||
107 | static int cntl_flags = CNTL_PASSWD|CNTL_SHADOW; | 108 | static int cntl_flags = CNTL_PASSWD|CNTL_SHADOW; |
108 | static long debug_level = 0; | 109 | static long debug_level = 0; |
109 | 110 | ||
110 | static regex_t rexp; | ||
111 | static const char *regex_str = NULL; | 111 | static const char *regex_str = NULL; |
112 | static int regex_flags = REG_EXTENDED; | 112 | static int regex_flags = REG_EXTENDED; |
113 | static int username_index = 1; | 113 | static long username_index = 1; |
114 | static int domain_index = 2; | 114 | static long domain_index = 2; |
115 | 115 | ||
116 | struct pam_opt pam_opt[] = { | 116 | struct 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 | ||
458 | static int | ||
459 | translate(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 | |||
441 | PAM_EXTERN int | 496 | PAM_EXTERN int |
442 | pam_sm_authenticate(pam_handle_t *pamh, int flags, | 497 | pam_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 |