1
0
mirror of https://github.com/Yubico/yubico-pam.git synced 2025-02-22 00:54:30 +01:00

enable that openvpn can now run without any local user

This commit is contained in:
Meno Abels 2014-10-29 13:25:29 +01:00
parent dae9380ac7
commit 37553c41ce
4 changed files with 94 additions and 19 deletions

21
README
View File

@ -345,5 +345,24 @@ Examples
If you want to use the Yubikey to authenticate you on linux console If you want to use the Yubikey to authenticate you on linux console
logins, add the following to the top of `/etc/pam.d/login`: logins, add the following to the top of `/etc/pam.d/login`:
auth sufficient pam_yubico.so id=16 debug auth sufficient pam_yubico.so id=16 debug
OpenVPN and ActiveDirectory
create file '/etc/pam.d/openvpn':
auth required pam_yubico.so ldap_uri=ldap://ldap-srv debug id=19 yubi_attr=pager
ldapdn=dc=ad,dc=next-audience,dc=net
ldap_filter=(&(sAMAccountName=%u)(memberOf=CN=mygroup,OU=DefaultUser,DC=adivser,DC=net))
ldap_bind_no_anonymous ldap_bind_user_filter=%u@adviser.com try_first_pass
account required pam_yubico.so
create file 'openvpn.conf'
plugin openvpn-plugin-auth-pam.so openvpn
Feedback
--------
If you want to discuss anything related to the Yubico PAM module,
please e-mail the mailing list yubico-devel@googlegroups.com.

View File

@ -114,6 +114,7 @@ struct cfg
const char *ldapserver; const char *ldapserver;
const char *ldap_uri; const char *ldap_uri;
int ldap_bind_no_anonymous; int ldap_bind_no_anonymous;
const char *ldap_bind_user_filter;
const char *ldap_bind_user; const char *ldap_bind_user;
const char *ldap_bind_password; const char *ldap_bind_password;
const char *ldap_filter; const char *ldap_filter;
@ -226,7 +227,7 @@ authorize_user_token_ldap (struct cfg *cfg,
struct berval **vals; struct berval **vals;
int i, rc; int i, rc;
const char *filter = NULL; char *filter = NULL;
char *find = NULL; char *find = NULL;
int scope = LDAP_SCOPE_BASE; int scope = LDAP_SCOPE_BASE;
#endif #endif
@ -263,16 +264,24 @@ authorize_user_token_ldap (struct cfg *cfg,
} }
/* LDAPv2 is historical -- RFC3494. */ /* LDAPv2 is historical -- RFC3494. */
ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
protocol = LDAP_VERSION3; protocol = LDAP_VERSION3;
ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol); ldap_set_option (ld, LDAP_OPT_PROTOCOL_VERSION, &protocol);
/* Bind anonymously to the LDAP server. */ /* Bind anonymously to the LDAP server. */
if (cfg->ldap_bind_user && cfg->ldap_bind_password) { if (cfg->ldap_bind_user && cfg->ldap_bind_password) {
DBG (("try bind with: %s:%s", cfg->ldap_bind_user, cfg->ldap_bind_password)); DBG (("try bind with: %s:[%s]", cfg->ldap_bind_user, cfg->ldap_bind_password));
rc = ldap_simple_bind_s (ld, cfg->ldap_bind_user, cfg->ldap_bind_password); rc = ldap_simple_bind_s (ld, cfg->ldap_bind_user, cfg->ldap_bind_password);
} else if (cfg->ldap_bind_no_anonymous) { } else if (cfg->ldap_bind_no_anonymous) {
DBG (("try bind with: %s:%s", user, password)); char *tmp_user;
rc = ldap_simple_bind_s (ld, user, password); if (cfg->ldap_bind_user_filter) {
tmp_user = filter_printf(cfg->ldap_bind_user_filter, user);
} else {
tmp_user = strdup(user);
}
DBG (("try bind with: %s:[XXXXX]", tmp_user, password));
rc = ldap_simple_bind_s (ld, tmp_user, password);
free(tmp_user);
} else { } else {
DBG (("try bind anonymous")); DBG (("try bind anonymous"));
rc = ldap_simple_bind_s (ld, NULL, NULL); rc = ldap_simple_bind_s (ld, NULL, NULL);
@ -331,16 +340,16 @@ authorize_user_token_ldap (struct cfg *cfg,
{ {
if ((vals = ldap_get_values_len (ld, e, a)) != NULL) if ((vals = ldap_get_values_len (ld, e, a)) != NULL)
{ {
DBG(("LDAP : Found %i values - checking if any of them match '%s:%s:%s'",
ldap_count_values_len(vals),
vals[i]->bv_val,
cfg->yubi_attr_prefix ? cfg->yubi_attr_prefix : "", token_id));
yubi_attr_prefix_len = cfg->yubi_attr_prefix ? strlen(cfg->yubi_attr_prefix) : 0; yubi_attr_prefix_len = cfg->yubi_attr_prefix ? strlen(cfg->yubi_attr_prefix) : 0;
/* Compare each value for the attribute against the token id. */ /* Compare each value for the attribute against the token id. */
for (i = 0; vals[i] != NULL; i++) for (i = 0; vals[i] != NULL; i++)
{ {
DBG(("LDAP : Found %i values - checking if any of them match '%s:%s:%s'",
ldap_count_values_len(vals),
vals[i]->bv_val,
cfg->yubi_attr_prefix ? cfg->yubi_attr_prefix : "", token_id));
/* Only values containing this prefix are considered. */ /* Only values containing this prefix are considered. */
if ((!cfg->yubi_attr_prefix || !strncmp (cfg->yubi_attr_prefix, vals[i]->bv_val, yubi_attr_prefix_len))) if ((!cfg->yubi_attr_prefix || !strncmp (cfg->yubi_attr_prefix, vals[i]->bv_val, yubi_attr_prefix_len)))
{ {
@ -690,6 +699,8 @@ parse_cfg (int flags, int argc, const char **argv, struct cfg *cfg)
cfg->ldap_bind_no_anonymous = 1; cfg->ldap_bind_no_anonymous = 1;
if (strncmp (argv[i], "ldap_bind_user=", sizeof("ldap_bind_user=")-1) == 0) if (strncmp (argv[i], "ldap_bind_user=", sizeof("ldap_bind_user=")-1) == 0)
cfg->ldap_bind_user = argv[i] + sizeof("ldap_bind_user=")-1; cfg->ldap_bind_user = argv[i] + sizeof("ldap_bind_user=")-1;
if (strncmp (argv[i], "ldap_bind_user_filter=", sizeof("ldap_bind_user_filter=")-1) == 0)
cfg->ldap_bind_user_filter = argv[i] + sizeof("ldap_bind_user_filter=")-1;
if (strncmp (argv[i], "ldap_bind_password=", sizeof("ldap_bind_password=")-1) == 0) if (strncmp (argv[i], "ldap_bind_password=", sizeof("ldap_bind_password=")-1) == 0)
cfg->ldap_bind_password = argv[i] + sizeof("ldap_bind_password=")-1; cfg->ldap_bind_password = argv[i] + sizeof("ldap_bind_password=")-1;
if (strncmp (argv[i], "ldap_filter=", sizeof("ldap_filter=")-1) == 0) if (strncmp (argv[i], "ldap_filter=", sizeof("ldap_filter=")-1) == 0)
@ -768,6 +779,7 @@ pam_sm_authenticate (pam_handle_t * pamh,
size_t templates = 0; size_t templates = 0;
char *urls[10]; char *urls[10];
char *tmpurl = NULL; char *tmpurl = NULL;
char *onlypasswd = NULL;
parse_cfg (flags, argc, argv, cfg); parse_cfg (flags, argc, argv, cfg);
@ -954,7 +966,6 @@ pam_sm_authenticate (pam_handle_t * pamh,
DBG (("OTP: %s ID: %s ", otp, otp_id)); DBG (("OTP: %s ID: %s ", otp, otp_id));
/* user entered their system password followed by generated OTP? */ /* user entered their system password followed by generated OTP? */
char *onlypasswd = NULL;
if (password_len > TOKEN_OTP_LEN + cfg->token_id_length) if (password_len > TOKEN_OTP_LEN + cfg->token_id_length)
{ {
onlypasswd = strdup (password); onlypasswd = strdup (password);
@ -970,7 +981,6 @@ pam_sm_authenticate (pam_handle_t * pamh,
"setting item PAM_AUTHTOK")); "setting item PAM_AUTHTOK"));
retval = pam_set_item (pamh, PAM_AUTHTOK, onlypasswd); retval = pam_set_item (pamh, PAM_AUTHTOK, onlypasswd);
free (onlypasswd);
if (retval != PAM_SUCCESS) if (retval != PAM_SUCCESS)
{ {
DBG (("set_item returned error: %s", pam_strerror (pamh, retval))); DBG (("set_item returned error: %s", pam_strerror (pamh, retval)));
@ -1029,6 +1039,8 @@ pam_sm_authenticate (pam_handle_t * pamh,
} }
done: done:
if (onlypasswd)
free(onlypasswd);
if (templates > 0) if (templates > 0)
{ {
size_t i; size_t i;
@ -1047,7 +1059,8 @@ done:
retval = PAM_SUCCESS; retval = PAM_SUCCESS;
} }
DBG (("done. [%s]", pam_strerror (pamh, retval))); DBG (("done. [%s]", pam_strerror (pamh, retval)));
pam_set_data (pamh, "yubico_setcred_return", (void*) (intptr_t) retval, NULL); pam_set_data (pamh, "yubico_setcred_return", (void*)(intptr_t)retval, NULL);
pam_set_data (pamh, "yubico_used_ldap", (void*)(intptr_t)cfg->ldap_bind_no_anonymous, NULL);
return retval; return retval;
} }
@ -1058,16 +1071,59 @@ pam_sm_setcred (pam_handle_t * pamh, int flags, int argc, const char **argv)
return PAM_SUCCESS; return PAM_SUCCESS;
} }
PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
{
int use_ldap = -1;
int rc = pam_get_data(pamh, "yubico_used_ldap", (const void**)&use_ldap);
if (rc == PAM_SUCCESS && use_ldap) {
int retval;
rc = pam_get_data(pamh, "yubico_setcred_return", (const void**)&retval);
if (rc == PAM_SUCCESS && retval == PAM_SUCCESS) {
D (("pam_sm_acct_mgmt returing PAM_SUCCESS"));
return PAM_SUCCESS;
}
}
D (("pam_sm_acct_mgmt returing PAM_AUTH_ERR:%d", use_ldap));
return PAM_AUTH_ERR;
}
PAM_EXTERN int
pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
D(("pam_sm_open_session"));
return (PAM_SUCCESS);
}
PAM_EXTERN int
pam_sm_close_session(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
D(("pam_sm_close_session"));
return (PAM_SUCCESS);
}
PAM_EXTERN int
pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
D(("pam_sm_chauthtok"));
return (PAM_SERVICE_ERR);
}
#ifdef PAM_STATIC #ifdef PAM_STATIC
struct pam_module _pam_yubico_modstruct = { struct pam_module _pam_yubico_modstruct = {
"pam_yubico", "pam_yubico",
pam_sm_authenticate, pam_sm_authenticate,
pam_sm_setcred, pam_sm_setcred,
NULL, pam_sm_acct_mgmt,
NULL, pam_sm_open_session,
NULL, pam_sm_close_session,
NULL pam_sm_chauthtok
}; };
#endif #endif

2
util.c
View File

@ -500,7 +500,7 @@ int filter_result_len(const char *filter, const char *user, char *output) {
return result_len + (filter+filter_len-result); return result_len + (filter+filter_len-result);
} }
const char *filter_printf(const char *filter, const char *user) { char *filter_printf(const char *filter, const char *user) {
char *result = malloc(filter_result_len(filter, user, NULL) + 1); char *result = malloc(filter_result_len(filter, user, NULL) + 1);
filter_result_len(filter, user, result); filter_result_len(filter, user, result);
return result; return result;

2
util.h
View File

@ -97,6 +97,6 @@ int challenge_response(YK_KEY *yk, int slot,
#endif /* HAVE_CR */ #endif /* HAVE_CR */
int filter_result_len(const char *filter, const char *user, char *output); int filter_result_len(const char *filter, const char *user, char *output);
const char *filter_printf(const char *filter, const char *user); char *filter_printf(const char *filter, const char *user);
#endif /* __PAM_YUBICO_UTIL_H_INCLUDED__ */ #endif /* __PAM_YUBICO_UTIL_H_INCLUDED__ */