summaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_sepermit/pam_sepermit.c
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/modules/pam_sepermit/pam_sepermit.c')
-rw-r--r--Linux-PAM/modules/pam_sepermit/pam_sepermit.c405
1 files changed, 0 insertions, 405 deletions
diff --git a/Linux-PAM/modules/pam_sepermit/pam_sepermit.c b/Linux-PAM/modules/pam_sepermit/pam_sepermit.c
deleted file mode 100644
index 47f95030..00000000
--- a/Linux-PAM/modules/pam_sepermit/pam_sepermit.c
+++ /dev/null
@@ -1,405 +0,0 @@
-/******************************************************************************
- * A module for Linux-PAM that allows/denies acces based on SELinux state.
- *
- * Copyright (c) 2007, 2008 Red Hat, Inc.
- * Originally written by Tomas Mraz <tmraz@redhat.com>
- * Contributions by Dan Walsh <dwalsh@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 <errno.h>
-#include <pwd.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <syslog.h>
-#include <ctype.h>
-#include <signal.h>
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <dirent.h>
-
-#define PAM_SM_AUTH
-#define PAM_SM_ACCOUNT
-
-#include <security/pam_modules.h>
-#include <security/_pam_macros.h>
-#include <security/pam_modutil.h>
-#include <security/pam_ext.h>
-
-#include <selinux/selinux.h>
-
-#define MODULE "pam_sepermit"
-#define OPT_DELIM ":"
-
-struct lockfd {
- uid_t uid;
- int fd;
- int debug;
-};
-
-#define PROC_BASE "/proc"
-#define MAX_NAMES (int)(sizeof(unsigned long)*8)
-
-static int
-match_process_uid(pid_t pid, uid_t uid)
-{
- char buf[128];
- uid_t puid;
- FILE *f;
- int re = 0;
-
- snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);
- if (!(f = fopen (buf, "r")))
- return 0;
-
- while (fgets(buf, sizeof buf, f)) {
- if (sscanf (buf, "Uid:\t%d", &puid)) {
- re = uid == puid;
- break;
- }
- }
- fclose(f);
- return re;
-}
-
-static int
-check_running (pam_handle_t *pamh, uid_t uid, int killall, int debug)
-{
- DIR *dir;
- struct dirent *de;
- pid_t *pid_table, pid, self;
- int i;
- int pids, max_pids;
- int running = 0;
- self = getpid();
- if (!(dir = opendir(PROC_BASE))) {
- pam_syslog(pamh, LOG_ERR, "Failed to open proc directory file %s:", PROC_BASE);
- return -1;
- }
- max_pids = 256;
- pid_table = malloc(max_pids * sizeof (pid_t));
- if (!pid_table) {
- pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
- return -1;
- }
- pids = 0;
- while ((de = readdir (dir)) != NULL) {
- if (!(pid = (pid_t)atoi(de->d_name)) || pid == self)
- continue;
-
- if (pids == max_pids) {
- if (!(pid_table = realloc(pid_table, 2*pids*sizeof(pid_t)))) {
- pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
- return -1;
- }
- max_pids *= 2;
- }
- pid_table[pids++] = pid;
- }
-
- (void)closedir(dir);
-
- for (i = 0; i < pids; i++) {
- pid_t id;
-
- if (match_process_uid(pid_table[i], uid) == 0)
- continue;
- id = pid_table[i];
-
- if (killall) {
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Attempting to kill %d", id);
- kill(id, SIGKILL);
- }
- running++;
- }
-
- free(pid_table);
- return running;
-}
-
-static void
-sepermit_unlock(pam_handle_t *pamh, void *plockfd, int error_status UNUSED)
-{
- struct lockfd *lockfd = plockfd;
- struct flock fl;
-
- memset(&fl, 0, sizeof(fl));
- fl.l_type = F_UNLCK;
- fl.l_whence = SEEK_SET;
-
- if (lockfd->debug)
- pam_syslog(pamh, LOG_ERR, "Unlocking fd: %d uid: %d", lockfd->fd, lockfd->uid);
-
- /* Don't kill uid==0 */
- if (lockfd->uid)
- /* This is a DOS but it prevents an app from forking to prevent killing */
- while(check_running(pamh, lockfd->uid, 1, lockfd->debug) > 0)
- continue;
-
- fcntl(lockfd->fd, F_SETLK, &fl);
- close(lockfd->fd);
- free(lockfd);
-}
-
-static int
-sepermit_lock(pam_handle_t *pamh, const char *user, int debug)
-{
- char buf[PATH_MAX];
- struct flock fl;
-
- memset(&fl, 0, sizeof(fl));
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
-
- struct passwd *pw = pam_modutil_getpwnam( pamh, user );
- if (!pw) {
- pam_syslog(pamh, LOG_ERR, "Unable to find uid for user %s", user);
- return -1;
- }
- if (check_running(pamh, pw->pw_uid, 0, debug) > 0) {
- pam_syslog(pamh, LOG_ERR, "User %s processes are running. Exclusive login not allowed", user);
- return -1;
- }
-
- snprintf(buf, sizeof(buf), "%s/%d.lock", SEPERMIT_LOCKDIR, pw->pw_uid);
- int fd = open(buf, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR);
- if (fd < 0) {
- pam_syslog(pamh, LOG_ERR, "Unable to open lock file %s/%d.lock", SEPERMIT_LOCKDIR, pw->pw_uid);
- return -1;
- }
-
- if (fcntl(fd, F_SETLK, &fl) == -1) {
- pam_syslog(pamh, LOG_ERR, "User %s with exclusive login already logged in", user);
- close(fd);
- return -1;
- }
- struct lockfd *lockfd=calloc(1, sizeof(struct lockfd));
- if (!lockfd) {
- close(fd);
- pam_syslog(pamh, LOG_CRIT, "Memory allocation error");
- return -1;
- }
- lockfd->uid = pw->pw_uid;
- lockfd->debug = debug;
- lockfd->fd=fd;
- pam_set_data(pamh, MODULE, lockfd, sepermit_unlock);
- return 0;
-}
-
-/* return 0 when matched, -1 when unmatched, pam error otherwise */
-static int
-sepermit_match(pam_handle_t *pamh, const char *cfgfile, const char *user,
- const char *seuser, int debug)
-{
- FILE *f;
- char *line = NULL;
- char *start;
- size_t len = 0;
- int matched = 0;
- int exclusive = 0;
-
- f = fopen(cfgfile, "r");
-
- if (!f) {
- pam_syslog(pamh, LOG_ERR, "Failed to open config file %s: %m", cfgfile);
- return PAM_SERVICE_ERR;
- }
-
- while (!matched && getline(&line, &len, f) != -1) {
- size_t n;
- char *sptr;
- char *opt;
-
- if (line[0] == '#')
- continue;
-
- start = line;
- while (isspace(*start))
- ++start;
- n = strlen(start);
- while (n > 0 && isspace(start[n-1])) {
- --n;
- }
- if (n == 0)
- continue;
-
- start[n] = '\0';
- start = strtok_r(start, OPT_DELIM, &sptr);
-
- switch (start[0]) {
- case '@':
- ++start;
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Matching user %s against group %s", user, start);
- if (pam_modutil_user_in_group_nam_nam(pamh, user, start)) {
- matched = 1;
- }
- break;
- case '%':
- ++start;
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Matching seuser %s against seuser %s", seuser, start);
- if (strcmp(seuser, start) == 0) {
- matched = 1;
- }
- break;
- default:
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Matching user %s against user %s", user, start);
- if (strcmp(user, start) == 0) {
- matched = 1;
- }
- }
- if (matched)
- while ((opt=strtok_r(NULL, OPT_DELIM, &sptr)) != NULL) {
- if (strcmp(opt, "exclusive") == 0)
- exclusive = 1;
- else if (debug) {
- pam_syslog(pamh, LOG_NOTICE, "Unknown user option: %s", opt);
- }
- }
- }
-
- free(line);
- fclose(f);
- if (matched)
- return exclusive ? sepermit_lock(pamh, user, debug) : 0;
- else
- return -1;
-}
-
-PAM_EXTERN int
-pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED,
- int argc, const char **argv)
-{
- int i;
- int rv;
- int debug = 0;
- int sense = PAM_AUTH_ERR;
- const char *user = NULL;
- char *seuser = NULL;
- char *level = NULL;
- const char *cfgfile = SEPERMIT_CONF_FILE;
-
- /* Parse arguments. */
- for (i = 0; i < argc; i++) {
- if (strcmp(argv[i], "debug") == 0) {
- debug = 1;
- }
- if (strcmp(argv[i], "conf=") == 0) {
- cfgfile = argv[i] + 5;
- }
- }
-
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Parsing config file: %s", cfgfile);
-
- if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
- || *user == '\0') {
- pam_syslog(pamh, LOG_ERR, "Cannot determine the user's name");
- return PAM_USER_UNKNOWN;
- }
-
- if (is_selinux_enabled() > 0) {
- if (security_getenforce() == 1) {
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "Enforcing mode, access will be allowed on match");
- sense = PAM_SUCCESS;
- }
-
- if (getseuserbyname(user, &seuser, &level) != 0) {
- seuser = NULL;
- level = NULL;
- pam_syslog(pamh, LOG_ERR, "getseuserbyname failed: %m");
- }
- }
-
- if (debug && sense != PAM_SUCCESS)
- pam_syslog(pamh, LOG_NOTICE, "Access will not be allowed on match");
-
- rv = sepermit_match(pamh, cfgfile, user, seuser, debug);
-
- if (debug)
- pam_syslog(pamh, LOG_NOTICE, "sepermit_match returned: %d", rv);
-
- free(seuser);
- free(level);
-
- switch (rv) {
- case -1:
- return PAM_IGNORE;
- case 0:
- return sense;
- }
-
- return rv;
-}
-
-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);
-}
-
-#ifdef PAM_STATIC
-
-/* static module data */
-
-struct pam_module _pam_sepermit_modstruct = {
- "pam_sepermit",
- pam_sm_authenticate,
- pam_sm_setcred,
- pam_sm_acct_mgmt,
- NULL,
- NULL,
- NULL
-};
-#endif
-