diff options
author | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 12:48:14 -0800 |
---|---|---|
committer | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 12:48:14 -0800 |
commit | d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c (patch) | |
tree | ba5654cffacfd2002eefc5bc3764a7971afff1dc /Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c | |
parent | 4c51da22e068907adb7857d50f5109a467c94d7c (diff) | |
parent | 7cbfa335c57d068d59508c844f3957165cccfb9b (diff) | |
download | pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.tar.gz pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.tar.bz2 pam-d5b06b67bbeeed7c05c0eb2e05d6a972ad050d1c.zip |
New upstream version 0.99.7.1
Diffstat (limited to 'Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c')
-rw-r--r-- | Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c | 256 |
1 files changed, 166 insertions, 90 deletions
diff --git a/Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c b/Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c index 23974afa..4f33ba2e 100644 --- a/Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c +++ b/Linux-PAM/modules/pam_succeed_if/pam_succeed_if.c @@ -37,7 +37,7 @@ * */ -#define _GNU_SOURCE +#include "config.h" #include <sys/types.h> #include <errno.h> @@ -52,34 +52,23 @@ #include <unistd.h> #include <pwd.h> #include <grp.h> -#include <security/pam_modules.h> -#include <security/_pam_modutil.h> +#include <netdb.h> -#define MODULE "pam_succeed_if" +#define PAM_SM_AUTH +#define PAM_SM_ACCOUNT +#define PAM_SM_SESSION +#define PAM_SM_PASSWORD -static void -log_error(int priority, const char *fmt, ...) -{ - va_list va; - char *fmt2; - fmt2 = malloc(strlen(fmt) + strlen(MODULE) + 3); - va_start(va, fmt); - if (fmt2 == NULL) { - vsyslog(LOG_AUTHPRIV | priority, fmt, va); - } else { - snprintf(fmt2, strlen(fmt) + strlen(MODULE) + 3, - "%s: %s", MODULE, fmt); - vsyslog(LOG_AUTHPRIV | priority, fmt2, va); - free(fmt2); - } - va_end(va); -} +#include <security/pam_modules.h> +#include <security/pam_modutil.h> +#include <security/pam_ext.h> /* Basically, run cmp(atol(left), atol(right)), returning PAM_SUCCESS if * the function returns non-zero, PAM_AUTH_ERR if it returns zero, and - * PAM_SYSTEM_ERR if the arguments can't be parsed as numbers. */ + * PAM_SERVICE_ERR if the arguments can't be parsed as numbers. */ static int -evaluate_num(const char *left, const char *right, int (*cmp)(int, int)) +evaluate_num(const pam_handle_t *pamh, const char *left, + const char *right, int (*cmp)(int, int)) { long l, r; char *p; @@ -88,20 +77,20 @@ evaluate_num(const char *left, const char *right, int (*cmp)(int, int)) errno = 0; l = strtol(left, &p, 0); if ((p == NULL) || (*p != '\0') || errno) { - log_error(LOG_INFO, "\"%s\" is not a number", left); + pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", left); ret = PAM_SERVICE_ERR; } r = strtol(right, &p, 0); if ((p == NULL) || (*p != '\0') || errno) { - log_error(LOG_INFO, "\"%s\" is not a number", right); + pam_syslog(pamh, LOG_INFO, "\"%s\" is not a number", right); ret = PAM_SERVICE_ERR; } if (ret != PAM_SUCCESS) { return ret; } - + return cmp(l, r) ? PAM_SUCCESS : PAM_AUTH_ERR; } @@ -139,9 +128,9 @@ ge(int i, int j) /* Test for numeric equality. */ static int -evaluate_eqn(const char *left, const char *right) +evaluate_eqn(const pam_handle_t *pamh, const char *left, const char *right) { - return evaluate_num(left, right, eq); + return evaluate_num(pamh, left, right, eq); } /* Test for string equality. */ static int @@ -151,9 +140,9 @@ evaluate_eqs(const char *left, const char *right) } /* Test for numeric inequality. */ static int -evaluate_nen(const char *left, const char *right) +evaluate_nen(const pam_handle_t *pamh, const char *left, const char *right) { - return evaluate_num(left, right, ne); + return evaluate_num(pamh, left, right, ne); } /* Test for string inequality. */ static int @@ -163,27 +152,27 @@ evaluate_nes(const char *left, const char *right) } /* Test for numeric less-than-ness(?) */ static int -evaluate_lt(const char *left, const char *right) +evaluate_lt(const pam_handle_t *pamh, const char *left, const char *right) { - return evaluate_num(left, right, lt); + return evaluate_num(pamh, left, right, lt); } /* Test for numeric less-than-or-equal-ness(?) */ static int -evaluate_le(const char *left, const char *right) +evaluate_le(const pam_handle_t *pamh, const char *left, const char *right) { - return evaluate_num(left, right, le); + return evaluate_num(pamh, left, right, le); } /* Test for numeric greater-than-ness(?) */ static int -evaluate_gt(const char *left, const char *right) +evaluate_gt(const pam_handle_t *pamh, const char *left, const char *right) { - return evaluate_num(left, right, gt); + return evaluate_num(pamh, left, right, gt); } /* Test for numeric greater-than-or-equal-ness(?) */ static int -evaluate_ge(const char *left, const char *right) +evaluate_ge(const pam_handle_t *pamh, const char *left, const char *right) { - return evaluate_num(left, right, ge); + return evaluate_num(pamh, left, right, ge); } /* Check for file glob match. */ static int @@ -197,34 +186,57 @@ evaluate_noglob(const char *left, const char *right) { return (fnmatch(right, left, 0) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR; } +/* Check for list match. */ +static int +evaluate_inlist(const char *left, const char *right) +{ + char *p; + if ((p=strstr(right, left)) == NULL) + return PAM_AUTH_ERR; + if (p == right || *(p-1) == ':') { /* ':' is a list separator */ + p += strlen(left); + if (*p == '\0' || *p == ':') { + return PAM_SUCCESS; + } + } + return PAM_AUTH_ERR; +} +/* Check for list mismatch. */ +static int +evaluate_notinlist(const char *left, const char *right) +{ + return evaluate_inlist(left, right) != PAM_SUCCESS ? PAM_SUCCESS : PAM_AUTH_ERR; +} /* Return PAM_SUCCESS if the user is in the group. */ static int evaluate_ingroup(pam_handle_t *pamh, const char *user, const char *group) { - int ret; - ret = _pammodutil_user_in_group_nam_nam(pamh, user, group); - switch (ret) { - case 1: + if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 1) return PAM_SUCCESS; - break; - default: - break; - } return PAM_AUTH_ERR; } /* Return PAM_SUCCESS if the user is NOT in the group. */ static int evaluate_notingroup(pam_handle_t *pamh, const char *user, const char *group) { - int ret; - ret = _pammodutil_user_in_group_nam_nam(pamh, user, group); - switch (ret) { - case 0: + if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 0) + return PAM_SUCCESS; + return PAM_AUTH_ERR; +} +/* Return PAM_SUCCESS if the (host,user) is in the netgroup. */ +static int +evaluate_innetgr(const char *host, const char *user, const char *group) +{ + if (innetgr(group, host, user, NULL) == 1) + return PAM_SUCCESS; + return PAM_AUTH_ERR; +} +/* Return PAM_SUCCESS if the (host,user) is NOT in the netgroup. */ +static int +evaluate_notinnetgr(const char *host, const char *user, const char *group) +{ + if (innetgr(group, host, user, NULL) == 0) return PAM_SUCCESS; - break; - default: - break; - } return PAM_AUTH_ERR; } @@ -261,38 +273,46 @@ evaluate(pam_handle_t *pamh, int debug, snprintf(buf, sizeof(buf), "%s", pwd->pw_dir); left = buf; } + if (strcasecmp(left, "service") == 0) { + const void *svc; + if (pam_get_item(pamh, PAM_SERVICE, &svc) != PAM_SUCCESS) + svc = ""; + snprintf(buf, sizeof(buf), "%s", (const char *)svc); + left = buf; + } /* If we have no idea what's going on, return an error. */ if (left != buf) { - log_error(LOG_CRIT, "unknown attribute \"%s\"", left); + pam_syslog(pamh, LOG_CRIT, "unknown attribute \"%s\"", left); return PAM_SERVICE_ERR; } if (debug) { - log_error(LOG_DEBUG, "'%s' resolves to '%s'", attribute, left); + pam_syslog(pamh, LOG_DEBUG, "'%s' resolves to '%s'", + attribute, left); } /* Attribute value < some threshold. */ if ((strcasecmp(qual, "<") == 0) || (strcasecmp(qual, "lt") == 0)) { - return evaluate_lt(left, right); + return evaluate_lt(pamh, left, right); } /* Attribute value <= some threshold. */ if ((strcasecmp(qual, "<=") == 0) || (strcasecmp(qual, "le") == 0)) { - return evaluate_le(left, right); + return evaluate_le(pamh, left, right); } /* Attribute value > some threshold. */ if ((strcasecmp(qual, ">") == 0) || (strcasecmp(qual, "gt") == 0)) { - return evaluate_gt(left, right); + return evaluate_gt(pamh, left, right); } /* Attribute value >= some threshold. */ if ((strcasecmp(qual, ">=") == 0) || (strcasecmp(qual, "ge") == 0)) { - return evaluate_ge(left, right); + return evaluate_ge(pamh, left, right); } /* Attribute value == some threshold. */ if (strcasecmp(qual, "eq") == 0) { - return evaluate_eqn(left, right); + return evaluate_eqn(pamh, left, right); } /* Attribute value = some string. */ if (strcasecmp(qual, "=") == 0) { @@ -300,7 +320,7 @@ evaluate(pam_handle_t *pamh, int debug, } /* Attribute value != some threshold. */ if (strcasecmp(qual, "ne") == 0) { - return evaluate_nen(left, right); + return evaluate_nen(pamh, left, right); } /* Attribute value != some string. */ if (strcasecmp(qual, "!=") == 0) { @@ -315,6 +335,13 @@ evaluate(pam_handle_t *pamh, int debug, (strcasecmp(qual, "noglob") == 0)) { return evaluate_noglob(left, right); } + /* Attribute value matches item in list. */ + if (strcasecmp(qual, "in") == 0) { + return evaluate_inlist(left, right); + } + if (strcasecmp(qual, "notin") == 0) { + return evaluate_notinlist(left, right); + } /* User is in this group. */ if (strcasecmp(qual, "ingroup") == 0) { return evaluate_ingroup(pamh, pwd->pw_name, right); @@ -323,14 +350,29 @@ evaluate(pam_handle_t *pamh, int debug, if (strcasecmp(qual, "notingroup") == 0) { return evaluate_notingroup(pamh, pwd->pw_name, right); } + /* (Rhost, user) is in this netgroup. */ + if (strcasecmp(qual, "innetgr") == 0) { + const void *rhost; + if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS) + rhost = NULL; + return evaluate_innetgr(rhost, pwd->pw_name, right); + } + /* (Rhost, user) is not in this group. */ + if (strcasecmp(qual, "notinnetgr") == 0) { + const void *rhost; + if (pam_get_item(pamh, PAM_RHOST, &rhost) != PAM_SUCCESS) + rhost = NULL; + return evaluate_notinnetgr(rhost, pwd->pw_name, right); + } /* Fail closed. */ return PAM_SERVICE_ERR; } -int -pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) +PAM_EXTERN int +pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, + int argc, const char **argv) { - const char *prompt; + const void *prompt; const char *user; struct passwd *pwd; int ret, i, count, use_uid, debug; @@ -338,7 +380,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) int quiet_fail, quiet_succ; /* Get the user prompt. */ - ret = pam_get_item(pamh, PAM_USER_PROMPT, (const void**) &prompt); + ret = pam_get_item(pamh, PAM_USER_PROMPT, &prompt); if ((ret != PAM_SUCCESS) || (prompt == NULL) || (strlen(prompt) == 0)) { prompt = "login: "; } @@ -366,29 +408,31 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) if (use_uid) { /* Get information about the user. */ - pwd = _pammodutil_getpwuid(pamh, getuid()); + pwd = pam_modutil_getpwuid(pamh, getuid()); if (pwd == NULL) { - log_error(LOG_CRIT, - "error retrieving information about user %ld", - (long)getuid()); - return PAM_SERVICE_ERR; + pam_syslog(pamh, LOG_CRIT, + "error retrieving information about user %lu", + (unsigned long)getuid()); + return PAM_USER_UNKNOWN; } + user = pwd->pw_name; } else { /* Get the user's name. */ ret = pam_get_user(pamh, &user, prompt); if ((ret != PAM_SUCCESS) || (user == NULL)) { - log_error(LOG_CRIT, "error retrieving user name: %s", - pam_strerror(pamh, ret)); + pam_syslog(pamh, LOG_CRIT, + "error retrieving user name: %s", + pam_strerror(pamh, ret)); return ret; } /* Get information about the user. */ - pwd = _pammodutil_getpwnam(pamh, user); + pwd = pam_modutil_getpwnam(pamh, user); if (pwd == NULL) { - log_error(LOG_CRIT, - "error retrieving information about user %s", - user); - return PAM_SERVICE_ERR; + pam_syslog(pamh, LOG_CRIT, + "error retrieving information about user %s", + user); + return PAM_USER_UNKNOWN; } } @@ -402,18 +446,18 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) pwd); if (ret != PAM_SUCCESS) { if(!quiet_fail) - log_error(LOG_INFO, - "requirement \"%s %s %s\" " - "not met by user \"%s\"", - left, qual, right, user); + pam_syslog(pamh, LOG_INFO, + "requirement \"%s %s %s\" " + "not met by user \"%s\"", + left, qual, right, user); break; } else if(!quiet_succ) - log_error(LOG_INFO, - "requirement \"%s %s %s\" " - "was met by user \"%s\"", - left, qual, right, user); + pam_syslog(pamh, LOG_INFO, + "requirement \"%s %s %s\" " + "was met by user \"%s\"", + left, qual, right, user); left = qual = right = NULL; } if ((i < argc) && (strcmp(argv[i], "debug") == 0)) { @@ -457,14 +501,46 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) return ret; } -int -pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) +PAM_EXTERN int +pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, + int argc UNUSED, const char **argv UNUSED) { - return PAM_SUCCESS; + return PAM_IGNORE; } -int +PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) { return pam_sm_authenticate(pamh, flags, argc, argv); } + +PAM_EXTERN int +pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + +PAM_EXTERN int +pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + +PAM_EXTERN int +pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) +{ + return pam_sm_authenticate(pamh, flags, argc, argv); +} + +/* static module data */ +#ifdef PAM_STATIC +struct pam_module _pam_succeed_if_modstruct = { + "pam_succeed_if", + pam_sm_authenticate, + pam_sm_setcred, + pam_sm_acct_mgmt, + pam_sm_open_session, + pam_sm_close_session, + pam_sm_chauthtok +}; +#endif |