diff options
Diffstat (limited to 'modules/pam_succeed_if/pam_succeed_if.c')
-rw-r--r-- | modules/pam_succeed_if/pam_succeed_if.c | 552 |
1 files changed, 0 insertions, 552 deletions
diff --git a/modules/pam_succeed_if/pam_succeed_if.c b/modules/pam_succeed_if/pam_succeed_if.c deleted file mode 100644 index 06cb5d6a..00000000 --- a/modules/pam_succeed_if/pam_succeed_if.c +++ /dev/null @@ -1,552 +0,0 @@ -/****************************************************************************** - * A simple user-attribute based module for PAM. - * - * Copyright (c) 2003 Red Hat, Inc. - * Written by Nalin Dahyabhai <nalin@redhat.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, and the entire permission notice in its entirety, - * including the disclaimer of warranties. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * ALTERNATIVELY, this product may be distributed under the terms of - * the GNU Public License, in which case the provisions of the GPL are - * required INSTEAD OF the above restrictions. (This clause is - * necessary due to a potential bad interaction between the GPL and - * the restrictions contained in a BSD-style copyright.) - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, - * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED - * OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "config.h" - -#include <sys/types.h> -#include <errno.h> -#include <fcntl.h> -#include <fnmatch.h> -#include <limits.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <syslog.h> -#include <unistd.h> -#include <pwd.h> -#include <grp.h> -#include <netdb.h> - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#define PAM_SM_SESSION -#define PAM_SM_PASSWORD - -#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_SERVICE_ERR if the arguments can't be parsed as numbers. */ -static int -evaluate_num(const pam_handle_t *pamh, const char *left, - const char *right, int (*cmp)(int, int)) -{ - long l, r; - char *p; - int ret = PAM_SUCCESS; - - errno = 0; - l = strtol(left, &p, 0); - if ((p == NULL) || (*p != '\0') || errno) { - 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) { - 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; -} - -/* Simple numeric comparison callbacks. */ -static int -eq(int i, int j) -{ - return i == j; -} -static int -ne(int i, int j) -{ - return i != j; -} -static int -lt(int i, int j) -{ - return i < j; -} -static int -le(int i, int j) -{ - return lt(i, j) || eq(i, j); -} -static int -gt(int i, int j) -{ - return i > j; -} -static int -ge(int i, int j) -{ - return gt(i, j) || eq(i, j); -} - -/* Test for numeric equality. */ -static int -evaluate_eqn(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, eq); -} -/* Test for string equality. */ -static int -evaluate_eqs(const char *left, const char *right) -{ - return (strcmp(left, right) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Test for numeric inequality. */ -static int -evaluate_nen(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, ne); -} -/* Test for string inequality. */ -static int -evaluate_nes(const char *left, const char *right) -{ - return (strcmp(left, right) != 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Test for numeric less-than-ness(?) */ -static int -evaluate_lt(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, lt); -} -/* Test for numeric less-than-or-equal-ness(?) */ -static int -evaluate_le(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, le); -} -/* Test for numeric greater-than-ness(?) */ -static int -evaluate_gt(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, gt); -} -/* Test for numeric greater-than-or-equal-ness(?) */ -static int -evaluate_ge(const pam_handle_t *pamh, const char *left, const char *right) -{ - return evaluate_num(pamh, left, right, ge); -} -/* Check for file glob match. */ -static int -evaluate_glob(const char *left, const char *right) -{ - return (fnmatch(right, left, 0) == 0) ? PAM_SUCCESS : PAM_AUTH_ERR; -} -/* Check for file glob mismatch. */ -static int -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; - /* Don't care about left containing ':'. */ - while ((p=strstr(right, left)) != NULL) { - if (p == right || *(p-1) == ':') { /* ':' is a list separator */ - p += strlen(left); - if (*p == '\0' || *p == ':') { - return PAM_SUCCESS; - } - } - right = strchr(p, ':'); - if (right == NULL) - break; - else - ++right; - } - 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) -{ - if (pam_modutil_user_in_group_nam_nam(pamh, user, group) == 1) - return PAM_SUCCESS; - 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) -{ - 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; - return PAM_AUTH_ERR; -} - -/* Match a triple. */ -static int -evaluate(pam_handle_t *pamh, int debug, - const char *left, const char *qual, const char *right, - struct passwd *pwd) -{ - char buf[LINE_MAX] = ""; - const char *attribute = left; - /* Figure out what we're evaluating here, and convert it to a string.*/ - if ((strcasecmp(left, "login") == 0) || - (strcasecmp(left, "name") == 0) || - (strcasecmp(left, "user") == 0)) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_name); - left = buf; - } - if (strcasecmp(left, "uid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_uid); - left = buf; - } - if (strcasecmp(left, "gid") == 0) { - snprintf(buf, sizeof(buf), "%lu", (unsigned long) pwd->pw_gid); - left = buf; - } - if (strcasecmp(left, "shell") == 0) { - snprintf(buf, sizeof(buf), "%s", pwd->pw_shell); - left = buf; - } - if ((strcasecmp(left, "home") == 0) || - (strcasecmp(left, "dir") == 0) || - (strcasecmp(left, "homedir") == 0)) { - 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) { - pam_syslog(pamh, LOG_CRIT, "unknown attribute \"%s\"", left); - return PAM_SERVICE_ERR; - } - if (debug) { - 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(pamh, left, right); - } - /* Attribute value <= some threshold. */ - if ((strcasecmp(qual, "<=") == 0) || - (strcasecmp(qual, "le") == 0)) { - return evaluate_le(pamh, left, right); - } - /* Attribute value > some threshold. */ - if ((strcasecmp(qual, ">") == 0) || - (strcasecmp(qual, "gt") == 0)) { - return evaluate_gt(pamh, left, right); - } - /* Attribute value >= some threshold. */ - if ((strcasecmp(qual, ">=") == 0) || - (strcasecmp(qual, "ge") == 0)) { - return evaluate_ge(pamh, left, right); - } - /* Attribute value == some threshold. */ - if (strcasecmp(qual, "eq") == 0) { - return evaluate_eqn(pamh, left, right); - } - /* Attribute value = some string. */ - if (strcasecmp(qual, "=") == 0) { - return evaluate_eqs(left, right); - } - /* Attribute value != some threshold. */ - if (strcasecmp(qual, "ne") == 0) { - return evaluate_nen(pamh, left, right); - } - /* Attribute value != some string. */ - if (strcasecmp(qual, "!=") == 0) { - return evaluate_nes(left, right); - } - /* Attribute value matches some pattern. */ - if ((strcasecmp(qual, "=~") == 0) || - (strcasecmp(qual, "glob") == 0)) { - return evaluate_glob(left, right); - } - if ((strcasecmp(qual, "!~") == 0) || - (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); - } - /* User is not in this group. */ - 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; -} - -PAM_EXTERN int -pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, - int argc, const char **argv) -{ - const void *prompt; - const char *user; - struct passwd *pwd; - int ret, i, count, use_uid, debug; - const char *left, *right, *qual; - int quiet_fail, quiet_succ; - - /* Get the user prompt. */ - ret = pam_get_item(pamh, PAM_USER_PROMPT, &prompt); - if ((ret != PAM_SUCCESS) || (prompt == NULL) || (strlen(prompt) == 0)) { - prompt = "login: "; - } - - quiet_fail = 0; - quiet_succ = 0; - for (use_uid = 0, debug = 0, i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug++; - } - if (strcmp(argv[i], "use_uid") == 0) { - use_uid++; - } - if (strcmp(argv[i], "quiet") == 0) { - quiet_fail++; - quiet_succ++; - } - if (strcmp(argv[i], "quiet_fail") == 0) { - quiet_fail++; - } - if (strcmp(argv[i], "quiet_success") == 0) { - quiet_succ++; - } - } - - if (use_uid) { - /* Get information about the user. */ - pwd = pam_modutil_getpwuid(pamh, getuid()); - if (pwd == NULL) { - 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)) { - pam_syslog(pamh, LOG_CRIT, - "error retrieving user name: %s", - pam_strerror(pamh, ret)); - return ret; - } - - /* Get information about the user. */ - pwd = pam_modutil_getpwnam(pamh, user); - if (pwd == NULL) { - pam_syslog(pamh, LOG_CRIT, - "error retrieving information about user %s", - user); - return PAM_USER_UNKNOWN; - } - } - - /* Walk the argument list. */ - i = count = 0; - left = qual = right = NULL; - while (i <= argc) { - if ((left != NULL) && (qual != NULL) && (right != NULL)) { - ret = evaluate(pamh, debug, - left, qual, right, - pwd); - if (ret != PAM_SUCCESS) { - if(!quiet_fail) - pam_syslog(pamh, LOG_INFO, - "requirement \"%s %s %s\" " - "not met by user \"%s\"", - left, qual, right, user); - break; - } - else - if(!quiet_succ) - 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)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "use_uid") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_fail") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_success") == 0)) { - i++; - continue; - } - if ((i < argc) && (left == NULL)) { - left = argv[i++]; - count++; - continue; - } - if ((i < argc) && (qual == NULL)) { - qual = argv[i++]; - count++; - continue; - } - if ((i < argc) && (right == NULL)) { - right = argv[i++]; - count++; - continue; - } - i++; - } - - return ret; -} - -PAM_EXTERN int -pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, - int argc UNUSED, const char **argv UNUSED) -{ - return PAM_IGNORE; -} - -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 |