Blame modules/pam_console/pam_console_apply.c

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