From c8826b402520ed12eacac695f06e17e65da23292 Mon Sep 17 00:00:00 2001 From: Jonathan Hall Date: Thu, 31 Mar 2016 01:02:58 +0200 Subject: [PATCH] Added authgroup PAM option for challenge-response mode to only require YubiKey for users in a specified group. --- AUTHORS | 4 ++++ pam_yubico.c | 17 ++++++++++++++++- util.c | 22 ++++++++++++++++++++++ util.h | 3 +++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index f8cf2842..1827fe48 100644 --- a/AUTHORS +++ b/AUTHORS @@ -42,3 +42,7 @@ Drop permissions before opening user files. Fredrik Thulin Maintainer alumni, helped on drop_privs.c, utils.c, and more. + +Jonathan D. Hall +Added authgroup PAM module option for challenge-response + diff --git a/pam_yubico.c b/pam_yubico.c index b1934361..1f939fb2 100644 --- a/pam_yubico.c +++ b/pam_yubico.c @@ -109,6 +109,7 @@ struct cfg int try_first_pass; int use_first_pass; const char *auth_file; + const char *auth_group; const char *capath; const char *cainfo; const char *proxy; @@ -439,7 +440,7 @@ do_challenge_response(pam_handle_t *pamh, struct cfg *cfg, const char *username) char *userfile = NULL, *tmpfile = NULL; FILE *f = NULL; char buf[CR_RESPONSE_SIZE + 16], response_hex[CR_RESPONSE_SIZE * 2 + 1]; - int ret, fd; + int ret, fd, result; unsigned int response_len = 0; YK_KEY *yk = NULL; @@ -449,6 +450,18 @@ do_challenge_response(pam_handle_t *pamh, struct cfg *cfg, const char *username) struct passwd *p; struct stat st; + + if(cfg->auth_group) { + result = check_user_group((char*)username,(char*)cfg->auth_group); + + if(result == 1) { + errstr = NULL; + errno = 0; + ret = PAM_SUCCESS; + DBG(("User %s is not in group %s - skipping YubiKey requirement for login!", username, cfg->auth_group)); + goto out; + } + } /* we must declare two sepparate privs structures as they can't be reused */ PAM_MODUTIL_DEF_PRIVS(privs); @@ -711,6 +724,8 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg) cfg->use_first_pass = 1; if (strncmp (argv[i], "authfile=", 9) == 0) cfg->auth_file = argv[i] + 9; + if (strncmp (argv[i], "authgroup=", 10) == 0) + cfg->auth_group = argv[i] + 10; if (strncmp (argv[i], "capath=", 7) == 0) cfg->capath = argv[i] + 7; if (strncmp (argv[i], "cainfo=", 7) == 0) diff --git a/util.c b/util.c index 3798faf4..7fef6ccd 100644 --- a/util.c +++ b/util.c @@ -226,6 +226,28 @@ check_firmware_version(YK_KEY *yk, bool verbose, bool quiet) return 1; } +int +check_user_group(char *username, char *group) +{ + struct group *group_ptr; + char **group_member; + + if((group_ptr = getgrnam(group)) == NULL) { + // Group was not found... Return a fail + D(("Group %s does not exist... Skipping group verification and returning valid!\n",group)); + return 1; + } + + for (group_member = group_ptr->gr_mem; *group_member != NULL; group_member++) { + if(strcmp(*group_member,username) == 0) { + // We found the user... + D(("User: %s is part of the Group: %s\n", username,group)); + return 0; + } + } + return 1; +} + int init_yubikey(YK_KEY **yk) { diff --git a/util.h b/util.h index 38526efe..b9e68f92 100644 --- a/util.h +++ b/util.h @@ -36,6 +36,8 @@ #include #include +#include +#include #include #if defined(DEBUG_PAM) @@ -90,6 +92,7 @@ int write_chalresp_state(FILE *f, CR_STATE *state); int init_yubikey(YK_KEY **yk); int check_firmware_version(YK_KEY *yk, bool verbose, bool quiet); +int check_user_group(char *username, char *group); int challenge_response(YK_KEY *yk, int slot, char *challenge, unsigned int len, bool hmac, bool may_block, bool verbose,