>From 65e46554c7ad85a6ad480303c93f4007f0bbe916 Mon Sep 17 00:00:00 2001 From: Felix Salfelder Date: Sat, 6 Dec 2014 16:07:44 +0100 Subject: [PATCH] private usersfile and optional flag --- pam_oath/pam_oath.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/pam_oath/pam_oath.c b/pam_oath/pam_oath.c index 8a17327..d12f7cf 100644 --- a/pam_oath/pam_oath.c +++ b/pam_oath/pam_oath.c @@ -26,6 +26,7 @@ #include #include #include +#include /* Libtool defines PIC for shared objects */ #ifndef PIC @@ -69,6 +70,7 @@ struct cfg int alwaysok; int try_first_pass; int use_first_pass; + int optional; char *usersfile; unsigned digits; unsigned window; @@ -83,6 +85,7 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) cfg->alwaysok = 0; cfg->try_first_pass = 0; cfg->use_first_pass = 0; + cfg->optional = 0; cfg->usersfile = NULL; cfg->digits = -1; cfg->window = 5; @@ -91,6 +94,8 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) { if (strcmp (argv[i], "debug") == 0) cfg->debug = 1; + if (strcmp (argv[i], "optional") == 0) + cfg->optional = 1; if (strcmp (argv[i], "alwaysok") == 0) cfg->alwaysok = 1; if (strcmp (argv[i], "try_first_pass") == 0) @@ -123,12 +128,45 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) D (("alwaysok=%d", cfg->alwaysok)); D (("try_first_pass=%d", cfg->try_first_pass)); D (("use_first_pass=%d", cfg->use_first_pass)); + D (("optional=%d", cfg->optional)); D (("usersfile=%s", cfg->usersfile ? cfg->usersfile : "(null)")); D (("digits=%d", cfg->digits)); D (("window=%d", cfg->window)); } } +static char* +prep_cfg (struct cfg *cfg, const char* user, char* scratch) +{ + char *hpos; + char *ret; + int size; + const struct passwd *pwent; + hpos = strstr(cfg->usersfile,"%h"); + + if(hpos) + { + if (cfg->debug) + D (("found %h for %s", user)); + pwent = getpwnam(user); + if(!pwent) return NULL; + if(!pwent->pw_dir) return NULL; + if(!*pwent->pw_dir) return NULL; + + size = strlen(cfg->usersfile) + strlen(pwent->pw_dir) - 1; + ret = (char*) malloc(size*sizeof(char)); + strncpy(ret, cfg->usersfile, hpos-cfg->usersfile); + strcpy(ret+(hpos-cfg->usersfile), pwent->pw_dir); + strcpy(ret+(hpos-cfg->usersfile)+strlen(pwent->pw_dir), hpos+2); + + cfg->usersfile = ret; + if(cfg->debug) + D (("usersfile=%s", cfg->usersfile)); + return ret; + } + return NULL; +} + PAM_EXTERN int pam_sm_authenticate (pam_handle_t * pamh, int flags, int argc, const char **argv) @@ -292,6 +330,21 @@ pam_sm_authenticate (pam_handle_t * pamh, { time_t last_otp; + char* scratch = NULL; + FILE* infh; + + scratch = prep_cfg(&cfg, user, scratch); + + if(cfg.optional) + { + infh = fopen (cfg.usersfile, "r"); + if (!infh) + { + DBG (("optional usersfile does not exist, PAM_SUCCESS")); + return PAM_SUCCESS; + } + fclose (infh); + } rc = oath_authenticate_usersfile (cfg.usersfile, user, @@ -299,6 +352,9 @@ pam_sm_authenticate (pam_handle_t * pamh, DBG (("authenticate rc %d (%s: %s) last otp %s", rc, oath_strerror_name (rc) ? oath_strerror_name (rc) : "UNKNOWN", oath_strerror (rc), ctime (&last_otp))); + + if (scratch) + free(scratch); } if (rc != OATH_OK) -- 2.0.0