>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