Blame modules/pam_console/pam_console_apply.c

Packit 7e982e
/*
Packit 7e982e
 * Read in the file, and grant ownerships to whoever has the lock.
Packit 7e982e
 */
Packit 7e982e
Packit 7e982e
#include "config.h"
Packit 7e982e
#include <errno.h>
Packit 7e982e
#include <pwd.h>
Packit 7e982e
#include <stdlib.h>
Packit 7e982e
#include <string.h>
Packit 7e982e
#include <syslog.h>
Packit 7e982e
#include <sys/types.h>
Packit 7e982e
#include <sys/stat.h>
Packit 7e982e
#include <sys/param.h>
Packit 7e982e
#include <fcntl.h>
Packit 7e982e
#include <unistd.h>
Packit 7e982e
#include <stdio.h>
Packit 7e982e
#include <stdarg.h>
Packit 7e982e
#include <glob.h>
Packit 7e982e
#include <locale.h>
Packit 7e982e
#define STATIC static
Packit 7e982e
#include "configfile.h"
Packit 7e982e
#include "chmod.h"
Packit 7e982e
#include "pam_console.h"
Packit 7e982e
Packit 7e982e
#include <security/_pam_macros.h>
Packit 7e982e
Packit 7e982e
#define CAST_ME_HARDER (const void**)
Packit 7e982e
#define DEFAULT_PERMSFILE "/etc/security/console.perms"
Packit 7e982e
#define PERMS_GLOB "/etc/security/console.perms.d/*.perms"
Packit 7e982e
Packit 7e982e
static const char consolelock[] = LOCKDIR "/" LOCKFILE;
Packit 7e982e
static char consoleperms[PATH_MAX];
Packit 7e982e
static char tty[PATH_MAX] = "tty0";
Packit 7e982e
static int debug = 0;
Packit 7e982e
static int syslogging = 0;
Packit 7e982e
Packit 7e982e
void
Packit 7e982e
_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...)
Packit 7e982e
{
Packit 7e982e
	va_list args;
Packit 7e982e
	if (debug_p && !debug) return;
Packit 7e982e
	va_start(args, format);
Packit 7e982e
	if (syslogging) {
Packit 7e982e
		vsyslog(err, format, args);
Packit 7e982e
	}
Packit 7e982e
	else {
Packit 7e982e
		vfprintf(stderr, format, args);
Packit 7e982e
		fprintf(stderr, "\n");
Packit 7e982e
	}
Packit 7e982e
	va_end(args);
Packit 7e982e
}
Packit 7e982e
Packit 7e982e
static void
Packit 7e982e
parse_files(void)
Packit 7e982e
{
Packit 7e982e
	int rc;
Packit 7e982e
	glob_t globbuf;
Packit 7e982e
	int i;
Packit 7e982e
	const char *oldlocale;
Packit 7e982e
Packit 7e982e
	/* first we parse the console.perms file */
Packit 7e982e
	parse_file(DEFAULT_PERMSFILE);
Packit 7e982e
Packit 7e982e
	/* set the LC_COLLATE so the sorting order doesn't depend
Packit 7e982e
	on system locale */
Packit 7e982e
	oldlocale = setlocale(LC_COLLATE, "C");
Packit 7e982e
Packit 7e982e
	rc = glob(PERMS_GLOB, 0, NULL, &globbuf);
Packit 7e982e
	setlocale(LC_COLLATE, oldlocale);
Packit 7e982e
	if (rc)
Packit 7e982e
		return;
Packit 7e982e
Packit 7e982e
	for (i = 0; globbuf.gl_pathv[i] != NULL; i++) {
Packit 7e982e
		parse_file(globbuf.gl_pathv[i]);
Packit 7e982e
	}
Packit 7e982e
	globfree(&globbuf);
Packit 7e982e
}
Packit 7e982e
Packit 7e982e
int
Packit 7e982e
main(int argc, char **argv)
Packit 7e982e
{
Packit 7e982e
	int fd;
Packit 7e982e
	int i, c;
Packit 7e982e
	struct stat st;
Packit 7e982e
	char *consoleuser = NULL;
Packit 7e982e
	enum {Set, Reset} sense = Set;
Packit 7e982e
	GSList *files = NULL;
Packit 7e982e
Packit 7e982e
	while((c = getopt(argc, argv, "c:f:t:rsd")) != -1) {
Packit 7e982e
		switch(c) {
Packit 7e982e
			case 'c': if (strlen(optarg) >= sizeof(consoleperms)) {
Packit 7e982e
					fprintf(stderr, "Console.perms filename too long\n");
Packit 7e982e
					exit(1);
Packit 7e982e
				  }
Packit 7e982e
				  strncpy(consoleperms, optarg, sizeof(consoleperms) - 1);
Packit 7e982e
				  consoleperms[sizeof(consoleperms) - 1] = '\0';
Packit 7e982e
				  break;
Packit 7e982e
			case 'f': chmod_set_fstab(optarg);
Packit 7e982e
				  break;
Packit 7e982e
			case 't': if (strlen(optarg) >= sizeof(tty)) {
Packit 7e982e
					fprintf(stderr, "TTY name too long\n");
Packit 7e982e
					exit(1);
Packit 7e982e
				  }
Packit 7e982e
				  strncpy(tty, optarg, sizeof(tty) - 1);
Packit 7e982e
				  tty[sizeof(tty) - 1] = '\0';
Packit 7e982e
				  break;
Packit 7e982e
			case 'r':
Packit 7e982e
				  sense = Reset;
Packit 7e982e
				  break;
Packit 7e982e
			case 's': 
Packit 7e982e
				  syslogging = TRUE;
Packit 7e982e
				  break;
Packit 7e982e
			case 'd': 
Packit 7e982e
				  debug = TRUE;
Packit 7e982e
				  break;
Packit 7e982e
			default:
Packit 7e982e
				  fprintf(stderr, "usage: %s [-f /etc/fstab] "
Packit 7e982e
					  "[-c %s] [-t tty] [-r] [-s] [-d] [<device file> ...]\n", argv[0],
Packit 7e982e
					  consoleperms);
Packit 7e982e
				  exit(1);
Packit 7e982e
		}
Packit 7e982e
	}
Packit 7e982e
Packit 7e982e
	if (syslogging)
Packit 7e982e
		openlog("pam_console_apply", LOG_CONS|LOG_PID, LOG_AUTH);
Packit 7e982e
Packit 7e982e
	for (i = argc-1; i >= optind;  i--) {
Packit 7e982e
		files = g_slist_prepend(files, argv[i]);
Packit 7e982e
        }
Packit 7e982e
Packit 7e982e
	if (*consoleperms == '\0')
Packit 7e982e
		parse_files();
Packit 7e982e
	else
Packit 7e982e
		parse_file(consoleperms);
Packit 7e982e
		
Packit 7e982e
        if (sense != Reset && (fd=open(consolelock, O_RDONLY)) != -1) {
Packit 7e982e
		if (fstat (fd, &st)) {
Packit 7e982e
			_pam_log(NULL, LOG_ERR, FALSE,
Packit 7e982e
			       "\"impossible\" fstat error on %s", consolelock);
Packit 7e982e
			close(fd);
Packit 7e982e
			goto return_error;
Packit 7e982e
		}
Packit 7e982e
		if (st.st_size) {
Packit 7e982e
			consoleuser = _do_malloc(st.st_size+1);
Packit 7e982e
			memset(consoleuser, '\0', st.st_size);
Packit 7e982e
			if ((i = read (fd, consoleuser, st.st_size)) == -1) {
Packit 7e982e
				_pam_log(NULL, LOG_ERR, FALSE,
Packit 7e982e
				       "\"impossible\" read error on %s",
Packit 7e982e
				       consolelock);
Packit 7e982e
				goto return_error;
Packit 7e982e
			}
Packit 7e982e
			consoleuser[i] = '\0';
Packit 7e982e
		}
Packit 7e982e
		close(fd);
Packit 7e982e
	} else {
Packit 7e982e
		sense = Reset;
Packit 7e982e
	}
Packit 7e982e
	if((sense == Set) && (consoleuser != NULL)) {
Packit 7e982e
		set_permissions(tty, consoleuser, files);
Packit 7e982e
	}
Packit 7e982e
	if(sense == Reset) {
Packit 7e982e
		reset_permissions(tty, files);
Packit 7e982e
	}
Packit 7e982e
	return 0;
Packit 7e982e
Packit 7e982e
return_error:
Packit 7e982e
	return 1;
Packit 7e982e
}