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 @@ -105,3 +105,4 @@ fgetpwent(FILE *fp) -char *sysconfdir = SYSCONFDIR; +static regex_t rexp; +static char *sysconfdir = SYSCONFDIR; static int cntl_flags = CNTL_PASSWD|CNTL_SHADOW; @@ -109,7 +110,6 @@ static long debug_level = 0; -static regex_t rexp; static const char *regex_str = NULL; static int regex_flags = REG_EXTENDED; -static int username_index = 1; -static int domain_index = 2; +static long username_index = 1; +static long domain_index = 2; @@ -141,2 +141,4 @@ 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 }, { NULL } @@ -164,5 +166,15 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv) } + if (username_index <= 0) { + _pam_log(LOG_CRIT, "username-index out of range"); + return PAM_AUTHINFO_UNAVAIL; + } + if (domain_index <= 0) { + _pam_log(LOG_CRIT, "domain-index out of range"); + return PAM_AUTHINFO_UNAVAIL; + } + if (cntl_flags & CNTL_REVERT_INDEX) { - username_index = 2; - domain_index = 1; + long t = username_index; + username_index = domain_index; + domain_index = t; } @@ -170,3 +182,3 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv) int rc; - if (rc = regcomp(&rexp, regex_str, regex_flags)) { + if ((rc = regcomp(&rexp, regex_str, regex_flags))) { size_t s = regerror(rc, &rexp, NULL, 0); @@ -184,7 +196,12 @@ _pam_parse(pam_handle_t *pamh, int argc, const char **argv) retval = PAM_AUTHINFO_UNAVAIL; - } else if (rexp.re_nsub != 2) { - _pam_log(LOG_NOTICE, - "invalid regular expression `%s': " - "must contain two reference groups", - regex_str); + } else if (!(username_index <= rexp.re_nsub + && domain_index <= rexp.re_nsub)) { + if (username_index > rexp.re_nsub) + _pam_log(LOG_NOTICE, + "not enough parenthesized groups" + " to satisfy username-index"); + if (domain_index > rexp.re_nsub) + _pam_log(LOG_NOTICE, + "not enough parenthesized groups" + " to satisfy domain-index"); regfree(&rexp); @@ -440,2 +457,40 @@ copy_backref (pam_handle_t *pamh, const char *name, +static int +translate(pam_handle_t *pamh, char const *input, + char **ret_username, char **ret_confdir) +{ + size_t nmatch = (domain_index > username_index + ? domain_index : username_index) + 1; + regmatch_t *rmatch; + int rc; + + rmatch = calloc(nmatch, sizeof(rmatch[0])); + if (!rmatch) { + _pam_log(LOG_ERR, "out of memory"); + return PAM_SERVICE_ERR; + } + + if (regexec(&rexp, input, nmatch, rmatch, 0) == 0) { + char *domain; + + if ((rc = copy_backref(pamh, "DOMAIN", input, rmatch, + domain_index, &domain)) == PAM_SUCCESS + && ((rc = copy_backref(pamh, "USERNAME", input, rmatch, + username_index, ret_username)) + == PAM_SUCCESS)) { + *ret_confdir = mkfilename(sysconfdir, domain); + pam_set_data(pamh, "CONFDIR", + (void *)*ret_confdir, gray_cleanup_string); + } + } else { + DEBUG(1,("user name `%s' does not match regular " + "expression `%s'", + input, + regex_str)); + rc = PAM_AUTH_ERR; + } + free(rmatch); + return rc; +} + PAM_EXTERN int @@ -444,3 +499,4 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, { - const char *username; + const char *input_username; + char *username; char *password; @@ -457,4 +513,4 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, /* Get the username */ - retval = pam_get_user(pamh, &username, NULL); - if (retval != PAM_SUCCESS || !username) { + retval = pam_get_user(pamh, &input_username, NULL); + if (retval != PAM_SUCCESS || !input_username) { DEBUG(1,("can not get the username")); @@ -466,25 +522,12 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, if (cntl_flags & CNTL_REGEX) { - regmatch_t rmatch[3]; - if (regexec(&rexp, username, 3, rmatch, 0) == 0) { - char *domain; - - rc = copy_backref(pamh, "DOMAIN", username, rmatch, - domain_index, &domain); - if (rc != PAM_SUCCESS) - return rc; - rc = copy_backref(pamh, "USERNAME", username, rmatch, - username_index, (char **) &username); - if (rc != PAM_SUCCESS) - return rc; - confdir = mkfilename(sysconfdir, domain); - pam_set_data(pamh, "CONFDIR", - (void *)confdir, gray_cleanup_string); - } else { - DEBUG(1,("user name `%s' does not match regular " - "expression `%s'", - username, - regex_str)); - } + retval = translate(pamh, input_username, &username, &confdir); regfree(&rexp); + } else { + retval = PAM_SUCCESS; + username = (char *) input_username; + confdir = sysconfdir; } + + if (retval != PAM_SUCCESS) + return retval; @@ -494,7 +537,2 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, - if (retval != PAM_SUCCESS) { - _pam_log(LOG_ERR, "Could not retrive user's password"); - return -2; - } - if (cntl_flags & CNTL_PASSWD) |