From f5ecaedc4b737c2f65aecb7283563bfac3a1fa95 Mon Sep 17 00:00:00 2001 From: tmraz Date: Dec 15 2005 12:16:13 +0000 Subject: 0.99.1-1: Thu Dec 15 2005 * Update all modules so they use automake infrastructure of the current Linux-PAM release. * Changed logging to pam_syslog. --- diff --git a/CHANGELOG b/CHANGELOG index 45d8195..002f93a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,12 @@ Changelog of pam-redhat modules This changelog describes only changes after branching of pam-redhat modules without autoconf support. +0.99.1-1: Thu Dec 15 2005 + +* Update all modules so they use automake infrastructure of the current + Linux-PAM release. +* Changed logging to pam_syslog. + 0.80-1: Thu Jul 14 2005 * pam_console: support perms.d directory with permissions files diff --git a/Makefile.pam-redhat b/Makefile.pam-redhat index 9e3d513..0ea1e20 100644 --- a/Makefile.pam-redhat +++ b/Makefile.pam-redhat @@ -1,4 +1,4 @@ -VERSION=0.80 +VERSION=0.99.1 RELEASE=1 CVSTAG=pam-redhat-$(shell echo $(VERSION) | sed s,\\.,-,g)-$(RELEASE) CVS_ROOT=$(shell cat CVS/Root) @@ -13,7 +13,7 @@ force-tag: cvs tag -cFR $(CVSTAG) . archive: tag - @rm -f pam-redhat-$(VERSION).tar.bz2 + @rm -f pam-redhat-$(VERSION)-$(RELEASE).tar.bz2 @rm -rf /tmp/modules cd /tmp; cvs -d $(CVS_ROOT) export -r$(CVSTAG) -d modules pam-redhat @dir=$$PWD; cd /tmp; tar cjf $$dir/pam-redhat-$(VERSION)-$(RELEASE).tar.bz2 $(patsubst %,modules/%,$(MODULES)) diff --git a/pam_chroot/Makefile.am b/pam_chroot/Makefile.am index b0520e1..34a794e 100644 --- a/pam_chroot/Makefile.am +++ b/pam_chroot/Makefile.am @@ -1,8 +1,21 @@ -include ../Makefile-module.am +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# -EXTRA_DIST = chroot.conf +CLEANFILES = *~ -securityconf_DATA = chroot.conf -module_LTLIBRARIES = pam_chroot.la -pam_chroot_la_SOURCES = pam_chroot.c -pam_chroot_la_LDFLAGS = $(MODULE_LDFLAGS) +EXTRA_DIST = README chroot.conf + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam +if HAVE_VERSIONING + AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif + +secureconf_DATA = chroot.conf +securelib_LTLIBRARIES = pam_chroot.la diff --git a/pam_chroot/pam_chroot.c b/pam_chroot/pam_chroot.c index 47ccf2b..1ad66d0 100644 --- a/pam_chroot/pam_chroot.c +++ b/pam_chroot/pam_chroot.c @@ -4,7 +4,7 @@ * $Id$ */ -#include "../config.h" +#include "config.h" #define PAM_SM_SESSION #include @@ -34,8 +34,6 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, char const *user; FILE *conf; - openlog("pam_chroot", LOG_PID, LOG_AUTHPRIV); - /* parse command-line arguments */ for(i = 0; i < argc; i++) { if(strcmp(argv[i], "debug") == 0) @@ -46,14 +44,14 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, } if((ret = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) { - syslog(LOG_ERR, "can't get username: %s", + pam_syslog(pamh, LOG_ERR, "can't get username: %s", pam_strerror(pamh, ret)); return ret; } conf = fopen(CONFIG, "r"); if(conf == NULL) { - syslog(LOG_ERR, "can't open config file \"" CONFIG "\": %s", + pam_syslog(pamh, LOG_ERR, "can't open config file \"" CONFIG "\": %s", strerror(errno)); return ret; } @@ -74,7 +72,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, continue; if((dir = strtok_r(NULL, " \t\r\n", &p)) == NULL) { - syslog(LOG_ERR, CONFIG ":%d: no directory", lineno); + pam_syslog(pamh, LOG_ERR, CONFIG ":%d: no directory", lineno); ret = onerr; break; } @@ -88,7 +86,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, memset(errbuf, 0, len + 1); regerror(err, &name_regex, errbuf, len); - syslog(LOG_ERR, CONFIG ":%d: illegal regex \"%s\": %s", + pam_syslog(pamh, LOG_ERR, CONFIG ":%d: illegal regex \"%s\": %s", lineno, name, errbuf); free(errbuf); @@ -105,32 +103,32 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, struct stat st; if (stat(dir, &st) == -1) { - syslog(LOG_ERR, "stat(%s) failed: %s", + pam_syslog(pamh, LOG_ERR, "stat(%s) failed: %s", dir, strerror(errno)); ret = onerr; } else /* Catch the most common misuse */ if (st.st_uid != 0 || (st.st_mode & (S_IWGRP | S_IWOTH))) { - syslog(LOG_ERR, "%s is writable by non-root", + pam_syslog(pamh, LOG_ERR, "%s is writable by non-root", dir); ret = onerr; } else if(chdir(dir) == -1) { - syslog(LOG_ERR, "chdir(%s) failed: %s", + pam_syslog(pamh, LOG_ERR, "chdir(%s) failed: %s", dir, strerror(errno)); ret = onerr; } else { if(debug) { - syslog(LOG_ERR, "chdir(%s) succeeded", + pam_syslog(pamh, LOG_ERR, "chdir(%s) succeeded", dir); } if(chroot(dir) == -1) { - syslog(LOG_ERR, "chroot(%s) failed: %s", + pam_syslog(pamh, LOG_ERR, "chroot(%s) failed: %s", dir, strerror(errno)); ret = onerr; } else { - syslog(LOG_ERR, "chroot(%s) succeeded", + pam_syslog(pamh, LOG_ERR, "chroot(%s) succeeded", dir); ret = PAM_SUCCESS; } @@ -140,7 +138,6 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags, } fclose(conf); - closelog(); return ret; } diff --git a/pam_console/.cvsignore b/pam_console/.cvsignore index e7d3714..7e6cc7e 100644 --- a/pam_console/.cvsignore +++ b/pam_console/.cvsignore @@ -1,3 +1,3 @@ -config.tab.c -config.tab.h -config.lex.c +configfile.tab.c +configfile.tab.h +configfile.lex.c diff --git a/pam_console/Makefile b/pam_console/Makefile deleted file mode 100644 index 39bfd3e..0000000 --- a/pam_console/Makefile +++ /dev/null @@ -1,149 +0,0 @@ -# -# This Makefile controls a build process of $(TITLE) module for -# Linux-PAM. You should not modify this Makefile (unless you know -# what you are doing!). -# - -include ../../Make.Rules - -TITLE=pam_console - -ifeq ($(PREFER_GLIB1),yes) -GLIB_CFLAGS = $(shell glib-config --cflags) -GLIB_LIBS = $(shell glib-config --libs) -else -GLIB_CFLAGS = $(shell pkg-config --cflags glib-2.0) -GLIB_LIBS = $(shell pkg-config --libs glib-2.0) -endif - -LOCKDIR = /var/run/console -LOCKMODE = 755 -LIBS += -L../pammodutil -lpammodutil - - -LOCAL_CONF1 = console.perms -INSTALLED_CONF1 = $(SCONFIGD)/console.perms -LOCAL_CONF2 = console.handlers -INSTALLED_CONF2 = $(SCONFIGD)/console.handlers -LOCAL_CONF3 = 50-default.perms -INSTALLED_CONF3 = $(SCONFIGD)/console.perms.d/50-default.perms -MAN5 = console.apps.5 console.perms.5 console.handlers.5 -MAN8 = pam_console.8 pam_console_apply.8 - -CFLAGS += $(GLIB_CFLAGS) -DLOCKDIR=\"$(LOCKDIR)\" -I../pammodutil/include -FLEX_OPTS = -Cr -BISON_OPTS = -d - -LIBSRC = pam_console.c pam_console.h regerr.c handlers.c handlers.h -BINSRC = pam_console_apply.c pam_console.h chmod.c modechange.c regerr.c config.lex.c config.tab.c config.h - -BINOBJ = $(TITLE)_apply.o -BINARY = $(TITLE)_apply - -LIBOBJ = $(TITLE).o -LIBOBJD = $(addprefix dynamic/,$(LIBOBJ)) -LIBOBJS = $(addprefix static/,$(LIBOBJ)) - -ifdef DYNAMIC -LIBSHARED = $(TITLE).so -endif - -ifdef STATIC -LIBSTATIC = lib$(TITLE).o -endif - -####################### don't edit below ####################### - -all: dirs $(LIBSHARED) $(LIBSTATIC) register $(BINARY) - -dynamic/%.o : %.c - $(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@ - -static/%.o : %.c - $(CC) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@ - -dirs: -ifdef DYNAMIC - @$(MKDIR) ./dynamic -endif -ifdef STATIC - @$(MKDIR) ./static -endif - -register: -ifdef STATIC - ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) ) -endif - -$(BINARY): $(BINOBJ) - $(LD) $(LDFLAGS) -o $@ $(BINOBJ) -Wl,-Bstatic $(GLIB_LIBS) -Wl,-Bdynamic ../../libpam/libpam.so -lc - -$(BINOBJ): $(BINSRC) - -ifdef DYNAMIC -$(LIBOBJD): $(LIBSRC) -endif - -ifdef DYNAMIC -$(LIBSHARED): $(LIBOBJD) - $(LD_D) $(LDFLAGS) -o $@ $(LIBOBJD) $(LIBS) $(NEED_LINK_LIB_C) - -endif - -ifdef STATIC -$(LIBOBJS): $(LIBSRC) -endif - -ifdef STATIC -$(LIBSTATIC): $(LIBOBJS) - $(LD) -r -o $@ $(LIBOBJS) $(LIBS) -endif - -install: all - $(MKDIR) $(FAKEROOT)$(SECUREDIR) -ifdef DYNAMIC - $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR) -endif -ifdef MAN3 - test -d $(FAKEROOT)$(MANDIR)/man3 || $(MKDIR) $(FAKEROOT)$(MANDIR)/man3 - $(INSTALL) -m $(MANMODE) $(MAN3) $(FAKEROOT)$(MANDIR)/man3/ -endif -ifdef MAN5 - test -d $(FAKEROOT)$(MANDIR)/man5 || $(MKDIR) $(FAKEROOT)$(MANDIR)/man5 - $(INSTALL) -m $(MANMODE) $(MAN5) $(FAKEROOT)$(MANDIR)/man5/ -endif -ifdef MAN8 - test -d $(FAKEROOT)$(MANDIR)/man8 || $(MKDIR) $(FAKEROOT)$(MANDIR)/man8 - $(INSTALL) -m $(MANMODE) $(MAN8) $(FAKEROOT)$(MANDIR)/man8/ -endif - if $(MKDIR) -m $(LOCKMODE) $(FAKEROOT)$(LOCKDIR) \ - $(FAKEROOT)/$(SCONFIGD)/console.apps $(FAKEROOT)/$(SCONFIGD)/console.perms.d; then \ - bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONF1)" "$(TITLE)" "$(LOCAL_CONF1)" ;\ - bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONF2)" "$(TITLE)" "$(LOCAL_CONF2)" ;\ - bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)/console.perms.d" "$(INSTALLED_CONF3)" "$(TITLE)" "$(LOCAL_CONF3)" ;\ - fi - test -d $(FAKEROOT)$(SUPLEMENTED) || install -m 755 -d $(FAKEROOT)$(SUPLEMENTED) - install -m 555 $(BINARY) $(FAKEROOT)$(SUPLEMENTED) - - -remove: - rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so - -clean: - rm -f $(BINARY) $(LIBOBJD) $(LIBOBJS) core *~ - rm -f *.a *.o *.so *.bak - rm -f config.tab.c config.tab.h config.lex.c - rm -rf dynamic static - $(CLEAN) - -.c.o: - $(CC) $(CFLAGS) -c $< - -config.tab.c: config.y - bison $(BISON_OPTS) -p _pc_yy $< - sh ./sed-static $@ - -config.lex.c: config.l config.tab.c - flex $(FLEX_OPTS) -o$@ -P_pc_yy $< - sh ./sed-static $@ - diff --git a/pam_console/Makefile.am b/pam_console/Makefile.am index 3851859..8fe27ac 100644 --- a/pam_console/Makefile.am +++ b/pam_console/Makefile.am @@ -1,40 +1,68 @@ -include ../Makefile-module.am - -AM_CFLAGS += @GLIB_CFLAGS@ -AM_LDFLAGS += @GLIB_LIBS@ - -EXTRA_DIST = \ - console.apps.5 console.perms.5 \ - pam_console.8 pam_console_apply.8 \ - console.perms - -securityconf_DATA = console.perms -consoleappsdir = $(securityconfdir)/console.apps -consolelockdir = $(LOCKDIR)/console - -install-data-local: - $(mkinstalldirs) $(DESTDIR)$(consoleappsdir) - $(mkinstalldirs) $(DESTDIR)$(consolelockdir) - -noinst_LTLIBRARIES = libpamconsole.la -libpamconsole_la_SOURCES = \ - chmod.c \ - chmod.h \ - config1.l \ - config2.y \ - modechange.c \ - modechange.h \ - pam_console.h \ - regerr.c - -module_LTLIBRARIES = pam_console.la -pam_console_la_SOURCES = pam_console.c -pam_console_la_LDFLAGS = $(MODULE_LDFLAGS) -pam_console_la_LIBADD = libpamconsole.la ../lib/libmisc.la +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# +CLEANFILES = *~ + +CONFFILES = console.perms console.handlers 50-default.perms +MAN5 = console.apps.5 console.perms.5 console.handlers.5 +MAN8 = pam_console.8 pam_console_apply.8 + +man_MANS = $(MAN5) $(MAN8) + +EXTRA_DIST = README $(man_MANS) $(CONFFILES) sed-static configfile.y configfile.l + +GLIB_CFLAGS = $(shell pkg-config --cflags glib-2.0) +# this ugly $(shell...) hack overrides automake checks when LDADD is used +GLIB_LIBS = $(shell echo '-Wl,-Bstatic') $(shell pkg-config '--libs' glib-2.0) $(shell echo '-Wl,-Bdynamic') + +LOCKDIR = /var/run/console +LOCKMODE = 755 + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) +permsddir = $(SCONFIGDIR)/console.perms.d + +noinst_HEADERS = chmod.h configfile.h configfile.tab.h handlers.h modechange.h pam_console.h + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ + $(GLIB_CFLAGS) -DLOCKDIR=\"$(LOCKDIR)\" + +pam_console_la_LDFLAGS = -no-undefined -avoid-version -module +if HAVE_VERSIONING + pam_console_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif +pam_console_la_LIBADD = -L$(top_builddir)/libpam -lpam + +# override extra dependencies otherwise we get GLIB_LIBS contents here +pam_console_apply_DEPENDENCIES = +# we can't use libtool (sorts linker options out of libraries) +pam_console_apply_LDADD = -L$(top_builddir)/libpam/.libs -lpam $(GLIB_LIBS) +pam_console_apply_LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ + +securelib_LTLIBRARIES = pam_console.la sbin_PROGRAMS = pam_console_apply -pam_console_apply_SOURCES = pam_console_apply.c -pam_console_apply_LDADD = libpamconsole.la ../lib/libmisc.la -lpam -ldl -man5_MANS = console.apps.5 console.perms.5 -man8_MANS = pam_console.8 pam_console_apply.8 + +secureconf_DATA = console.perms console.handlers +permsd_DATA = 50-default.perms + +FLEX_OPTS = -Cr +BISON_OPTS = -d + +pam_console_la_SOURCES = pam_console.c pam_console.h regerr.c handlers.c handlers.h +pam_console_apply_SOURCES = pam_console_apply.c pam_console.h chmod.c modechange.c regerr.c configfile.c configfile.h + +pam_console_la_CFLAGS = $(AM_CFLAGS) +pam_console_apply_CFLAGS = $(AM_CFLAGS) + +configfile.tab.c: configfile.y + $(YACC) $(BISON_OPTS) -p _pc_yy $< + sh $(srcdir)/sed-static $@ + +configfile.lex.c: configfile.l configfile.tab.c + $(LEX) $(FLEX_OPTS) -o$@ -P_pc_yy $< + sh $(srcdir)/sed-static $@ + +configfile.c: configfile.tab.c configfile.lex.c diff --git a/pam_console/chmod.c b/pam_console/chmod.c index 8a972c3..38c09e4 100644 --- a/pam_console/chmod.c +++ b/pam_console/chmod.c @@ -21,7 +21,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "../../_pam_aconf.h" +#include "config.h" #include #include #include @@ -35,8 +35,6 @@ #include #define NAMLEN(dirent) strlen((dirent)->d_name) -#include - #include "chmod.h" #include "modechange.h" @@ -134,7 +132,7 @@ change_file (const char *file, const struct mode_change *changes, return errors; } -static void +void chmod_set_fstab(const char *fstab) { fstab_filename = strdup(fstab); diff --git a/pam_console/chmod.h b/pam_console/chmod.h index 738e807..8b585a1 100644 --- a/pam_console/chmod.h +++ b/pam_console/chmod.h @@ -4,11 +4,9 @@ #ifndef _CHMOD_H #define _CHMOD_H -#ifndef STATIC -#define STATIC -#endif - -STATIC int chmod_files (const char *mode, uid_t user, gid_t group, char *filename, GSList *filelist, GSList *constraints); -STATIC void chmod_set_fstab(const char *fstab); +int +chmod_files(const char *mode, uid_t user, gid_t group, char *filename, GSList *filelist, GSList *constraints); +void +chmod_set_fstab(const char *fstab); #endif /* _CHMOD_H */ diff --git a/pam_console/config.h b/pam_console/config.h deleted file mode 100644 index 2fecad2..0000000 --- a/pam_console/config.h +++ /dev/null @@ -1,37 +0,0 @@ -/* Copyright 1999, 2005 Red Hat, Inc. - * This software may be used under the terms of the GNU General Public - * License, available in the file COPYING accompanying this file. - */ -#ifndef _CONFIG_H -#define _CONFIG_H -#include - -typedef struct class_s class; -struct class_s { - char* name; - GSList* list; -}; - -typedef struct config_s config; -struct config_s { - class* console_class; - char* mode; - class* device_class; - char* revert_mode; - char* revert_owner; - char* revert_group; -}; - -STATIC void -parse_file(const char *name); - -STATIC int -check_console_name (const char *consolename); - -STATIC int -set_permissions(const char *consolename, const char *username, GSList *files); - -STATIC int -reset_permissions(const char *consolename, GSList *files); - -#endif /* _CONFIG_H */ diff --git a/pam_console/config.l b/pam_console/config.l deleted file mode 100644 index 2b8b34d..0000000 --- a/pam_console/config.l +++ /dev/null @@ -1,63 +0,0 @@ -%option noyywrap -%{ -/* Copyright 1999,2000 Red Hat, Inc. - * This software may be used under the terms of the GNU General Public - * License, available in the file COPYING accompanying this file - */ -/* get around an apparant bug in bison; YYSTYPE not copied into config.tab.h */ -#define YYSTYPE void * -#include "config.tab.h" -#include -#include -#include - -static int lineno; -static const char *filename; - -STATIC char * -strip_slash(const char *); -%} -%% -\n { lineno++; return EOL; } -\\\n { lineno++; } - /* do not return EOL, eat up escaped newline */ -[ \t]+ /* ignore whitespace */ -\< { return OBRACKET; } -\>= { return CBEQUALS; } -\> { return CBRACKET; } -([^\t\n #\<\>]|(\\#|\\\<|\\\>))+ { _pc_yylval=strip_slash(yytext); return STRING; } -#.*\n { lineno++; return EOL; } /* ignore comments */ -%% - -static void -lex_file (FILE *in) { - /* yy_flex_debug = 1; */ - yyin = in; - lineno = 1; -} - -static void -lex_set_filename(const char *name) { - filename = name; -} - -static int -_pc_yyerror (const char *s) { - _pam_log(LOG_ERR, 0, "%s line %d: %s: at `%s'\n", - filename, lineno, s, (char *)_pc_yylval); - return 0; -} - -STATIC char * -strip_slash(const char *s) { - char *r, *t; - - t = r = g_strdup(s); - while ((t = strchr(t, '\\')) != NULL) { - if (t[1] == '#' || t[1] == '<' || t[1] == '>') { - memmove(t, t+1, strlen(t)); - } - t++; - } - return r; -} diff --git a/pam_console/config.y b/pam_console/config.y deleted file mode 100644 index 81e5f0a..0000000 --- a/pam_console/config.y +++ /dev/null @@ -1,298 +0,0 @@ -%{ -/* Copyright 1999,2000 Red Hat, Inc. - * This software may be used under the terms of the GNU General Public - * License, available in the file COPYING accompanying this file - */ -#define YYSTYPE void * - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static GHashTable *namespace = NULL; -static GSList *configList = NULL; -static GSList *configListEnd = NULL; -static GSList *consoleClassList = NULL; -static GSList *consoleClassListEnd = NULL; -static const char *consoleNameCache = NULL; -static GHashTable *consoleHash = NULL; - -static void -do_yyerror(const char *format, ...); - -static void -empty_class(class *c); - -%} - -%token EOL -%token OBRACKET -%token CBEQUALS -%token CBRACKET -%token STRING - -%% -lines: lines line - | /* empty */ - ; - -line: config - | classdef - | EOL - | error - ; - -classdef: - OBRACKET string CBEQUALS stringlist EOL { - class *c; - - c = g_hash_table_lookup(namespace, $2); - if (c) { - empty_class(c); - } else { - c = g_malloc(sizeof(class)); - g_hash_table_insert(namespace, g_strdup($2), c); - } - c->name = $2; - c->list = $4; - } - ; - -config: classlist STRING classlist optstring optstring EOL { - config *conf = g_malloc(sizeof(config)); - conf->console_class = $1; - conf->mode = $2; - conf->device_class = $3; - conf->revert_mode = $4; - conf->revert_owner = $5; - if (conf->revert_owner != NULL) { - conf->revert_group = strchr (conf->revert_owner, ':'); - if (conf->revert_group == NULL) - conf->revert_group = strchr (conf->revert_owner, '.'); - if (conf->revert_group != NULL) { - *(conf->revert_group) = '\0'; - conf->revert_group++; - if (*(conf->revert_group) == '\0') - conf->revert_group = NULL; - if (*(conf->revert_owner) == '\0') - conf->revert_owner = NULL; - } - } - configListEnd = g_slist_append(configListEnd, conf); - if (configListEnd->next) configListEnd = configListEnd->next; - if (!configList) configList = configListEnd; - consoleClassListEnd = - g_slist_append(consoleClassListEnd, conf->console_class); - if (consoleClassListEnd->next) - consoleClassListEnd = consoleClassListEnd->next; - if (!consoleClassList) consoleClassList = consoleClassListEnd; - } - ; - -classlist: OBRACKET string CBRACKET { - class *c = g_hash_table_lookup(namespace, $2); - if(!c) { - _pam_log(LOG_ERR, FALSE, - "unknown class \"%s\" at line %d in %s\n", - (const char *)$2, lineno, filename); - _exit(1); - } - $$ = c; - } - | string { - class *c = g_malloc(sizeof(class)); - c->name = $1; - c->list = NULL; - $$ = c; - } - ; - - -stringlist: string {$$ = g_slist_append(NULL, $1);} - | stringlist string {$$ = g_slist_append($1, $2);} - ; - -optstring: string {$$=$1;} - | /* empty */ {$$=NULL;} - ; - -string: STRING {$$=$1;} ; - -%% - -/* exported functions */ - -/* parse a file given by a name */ -STATIC void -parse_file(const char *name) { - FILE *infile; - - _pam_log(LOG_DEBUG, TRUE, "parsing config file %s", name); - infile = fopen(name, "r"); - if (!infile) { - _pam_log(LOG_ERR, FALSE, "could not parse required file %s", name); - return; - } - - if (!namespace) namespace = g_hash_table_new(g_str_hash, g_str_equal); - - lex_set_filename(name); - lex_file(infile); - - yyparse(); - fclose(infile); -} - -static int -check_one_console_name (const char *name, char *classComponent) { - regex_t p; - int r_err; - char *class_exp; - - class_exp = _do_malloc(strlen(classComponent) + 3); - sprintf(class_exp, "^%s$", classComponent); - r_err = regcomp(&p, class_exp, REG_EXTENDED|REG_NOSUB); - if (r_err) do_regerror(r_err, &p); - r_err = regexec(&p, name, 0, NULL, 0); - regfree(&p); - free (class_exp); - return !r_err; -} - -STATIC int -check_console_name (const char *consolename) { - GSList *this_class; - GSList *this_list; - class *c; - int found = 0; - - _pam_log(LOG_DEBUG, TRUE, "check console %s", consolename); - if (consoleNameCache != consolename) { - consoleNameCache = consolename; - if (consoleHash) g_hash_table_destroy(consoleHash); - consoleHash = g_hash_table_new(NULL, NULL); - } - for (this_class = consoleClassList; this_class; - this_class = this_class->next) { - c = this_class->data; - if (c->list) { - for (this_list = c->list; this_list; this_list = this_list->next) { - if (check_one_console_name(consolename, this_list->data)) { - g_hash_table_insert(consoleHash, c, c); - found = 1; - } - } - } else { - if (check_one_console_name(consolename, c->name)) { - g_hash_table_insert(consoleHash, c, c); - found = 1; - } - } - } - - if (found) - return 1; - - /* not found */ - _pam_log(LOG_INFO, TRUE, "did not find console %s", consolename); - if (consoleHash) { - g_hash_table_destroy(consoleHash); - consoleHash = NULL; - } - return 0; -} - -STATIC int -set_permissions(const char *consolename, const char *username, GSList *files) { - struct passwd *pwd; - config *c; - GSList *cl; - - if (!consoleNameCache || strcmp(consolename, consoleNameCache)) { - if (!check_console_name(consolename)) return -1; - } - - pwd = getpwnam(username); - if (pwd == NULL) { - _pam_log(LOG_ERR, FALSE, "getpwnam failed for \"%s\"", username); - return -1; - } - - for (cl = configList; cl; cl = cl->next) { - c = cl->data; - if (g_hash_table_lookup(consoleHash, c->console_class)) { - if (c->device_class->list) - chmod_files(c->mode, pwd->pw_uid, -1, NULL, c->device_class->list, files); - else - chmod_files(c->mode, pwd->pw_uid, -1, c->device_class->name, NULL, files); - } - } - return 0; -} - -STATIC int -reset_permissions(const char *consolename, GSList *files) { - struct passwd *pwd; - struct group *grp; - config *c; - GSList *cl; - - if (!consoleNameCache || strcmp(consolename, consoleNameCache)) { - if (!check_console_name(consolename)) return -1; - } - - for (cl = configList; cl; cl = cl->next) { - c = cl->data; - if (g_hash_table_lookup(consoleHash, c->console_class)) { - pwd = getpwnam(c->revert_owner ? c->revert_owner : "root"); - if (pwd == NULL) { - _pam_log(LOG_ERR, FALSE, "getpwnam failed for %s", - c->revert_owner ? c->revert_owner : "root"); - return -1; - } - grp = getgrnam(c->revert_group ? c->revert_group : "root"); - if (grp == NULL) { - _pam_log(LOG_ERR, FALSE, "getgrnam failed for %s", - c->revert_group ? c->revert_group : "root"); - return -1; - } - if (c->device_class->list) - chmod_files(c->revert_mode ? c->revert_mode : "0600", - pwd->pw_uid, grp->gr_gid, NULL, c->device_class->list, files); - else - chmod_files(c->revert_mode ? c->revert_mode : "0600", - pwd->pw_uid, grp->gr_gid, c->device_class->name, NULL, files); - } - } - return 0; -} - - - - -/* local, static functions */ - -static void -do_yyerror(const char *format, ...) { - va_list ap; - - va_start(ap, format); - openlog("pam_console", LOG_CONS|LOG_PID, LOG_AUTHPRIV); - vsyslog(LOG_PID|LOG_AUTHPRIV|LOG_ERR, format, ap); - va_end(ap); -} - -static void -empty_class(class *c) { - g_free(c->name); - c->name = NULL; - g_slist_free(c->list); - c->list = NULL; -} diff --git a/pam_console/configfile.c b/pam_console/configfile.c new file mode 100644 index 0000000..6225a86 --- /dev/null +++ b/pam_console/configfile.c @@ -0,0 +1,16 @@ +#include +#include +#include "configfile.h" + +void * +_do_malloc(size_t req) +{ + void *ret; + ret = malloc(req); + if (!ret) abort(); + return ret; +} + +#include "configfile.lex.c" +#include "configfile.tab.c" + diff --git a/pam_console/configfile.h b/pam_console/configfile.h new file mode 100644 index 0000000..c3b566d --- /dev/null +++ b/pam_console/configfile.h @@ -0,0 +1,41 @@ +/* Copyright 1999, 2005 Red Hat, Inc. + * This software may be used under the terms of the GNU General Public + * License, available in the file COPYING accompanying this file. + */ +#ifndef _CONFIG_H +#define _CONFIG_H +#include +#define STATIC static + +typedef struct class_s class; +struct class_s { + char* name; + GSList* list; +}; + +typedef struct config_s config; +struct config_s { + class* console_class; + char* mode; + class* device_class; + char* revert_mode; + char* revert_owner; + char* revert_group; +}; + +void +parse_file(const char *name); + +int +check_console_name (const char *consolename); + +int +set_permissions(const char *consolename, const char *username, GSList *files); + +int +reset_permissions(const char *consolename, GSList *files); + +void * +_do_malloc(size_t req); + +#endif /* _CONFIG_H */ diff --git a/pam_console/configfile.l b/pam_console/configfile.l new file mode 100644 index 0000000..61c1e5a --- /dev/null +++ b/pam_console/configfile.l @@ -0,0 +1,67 @@ +%option noyywrap +%{ +/* Copyright 1999,2000 Red Hat, Inc. + * This software may be used under the terms of the GNU General Public + * License, available in the file COPYING accompanying this file + */ +/* get around an apparant bug in bison; YYSTYPE not copied into config.tab.h */ +#define YYSTYPE void * +#include "configfile.h" +#include "configfile.tab.h" +#include +#include +#include +#include + +#include "pam_console.h" + +static int lineno; +static const char *filename; + +STATIC char * +strip_slash(const char *); +%} +%% +\n { lineno++; return EOL; } +\\\n { lineno++; } + /* do not return EOL, eat up escaped newline */ +[ \t]+ /* ignore whitespace */ +\< { return OBRACKET; } +\>= { return CBEQUALS; } +\> { return CBRACKET; } +([^\t\n #\<\>]|(\\#|\\\<|\\\>))+ { _pc_yylval=strip_slash(yytext); return STRING; } +#.*\n { lineno++; return EOL; } /* ignore comments */ +%% + +static void +lex_file (FILE *in) { + /* yy_flex_debug = 1; */ + yyin = in; + lineno = 1; +} + +static void +lex_set_filename(const char *name) { + filename = name; +} + +static int +_pc_yyerror (const char *s) { + _pam_log(NULL, LOG_ERR, 0, "%s line %d: %s: at `%s'\n", + filename, lineno, s, (char *)_pc_yylval); + return 0; +} + +STATIC char * +strip_slash(const char *s) { + char *r, *t; + + t = r = g_strdup(s); + while ((t = strchr(t, '\\')) != NULL) { + if (t[1] == '#' || t[1] == '<' || t[1] == '>') { + memmove(t, t+1, strlen(t)); + } + t++; + } + return r; +} diff --git a/pam_console/configfile.y b/pam_console/configfile.y new file mode 100644 index 0000000..a9b45eb --- /dev/null +++ b/pam_console/configfile.y @@ -0,0 +1,301 @@ +%{ +/* Copyright 1999,2000 Red Hat, Inc. + * This software may be used under the terms of the GNU General Public + * License, available in the file COPYING accompanying this file + */ +#define YYSTYPE void * + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static GHashTable *namespace = NULL; +static GSList *configList = NULL; +static GSList *configListEnd = NULL; +static GSList *consoleClassList = NULL; +static GSList *consoleClassListEnd = NULL; +static const char *consoleNameCache = NULL; +static GHashTable *consoleHash = NULL; + +static void +do_yyerror(const char *format, ...); + +static void +empty_class(class *c); + +%} + +%token EOL +%token OBRACKET +%token CBEQUALS +%token CBRACKET +%token STRING + +%% +lines: lines line + | /* empty */ + ; + +line: config + | classdef + | EOL + | error + ; + +classdef: + OBRACKET string CBEQUALS stringlist EOL { + class *c; + + c = g_hash_table_lookup(namespace, $2); + if (c) { + empty_class(c); + } else { + c = g_malloc(sizeof(class)); + g_hash_table_insert(namespace, g_strdup($2), c); + } + c->name = $2; + c->list = $4; + } + ; + +config: classlist STRING classlist optstring optstring EOL { + config *conf = g_malloc(sizeof(config)); + conf->console_class = $1; + conf->mode = $2; + conf->device_class = $3; + conf->revert_mode = $4; + conf->revert_owner = $5; + if (conf->revert_owner != NULL) { + conf->revert_group = strchr (conf->revert_owner, ':'); + if (conf->revert_group == NULL) + conf->revert_group = strchr (conf->revert_owner, '.'); + if (conf->revert_group != NULL) { + *(conf->revert_group) = '\0'; + conf->revert_group++; + if (*(conf->revert_group) == '\0') + conf->revert_group = NULL; + if (*(conf->revert_owner) == '\0') + conf->revert_owner = NULL; + } + } + configListEnd = g_slist_append(configListEnd, conf); + if (configListEnd->next) configListEnd = configListEnd->next; + if (!configList) configList = configListEnd; + consoleClassListEnd = + g_slist_append(consoleClassListEnd, conf->console_class); + if (consoleClassListEnd->next) + consoleClassListEnd = consoleClassListEnd->next; + if (!consoleClassList) consoleClassList = consoleClassListEnd; + } + ; + +classlist: OBRACKET string CBRACKET { + class *c = g_hash_table_lookup(namespace, $2); + if(!c) { + _pam_log(NULL, LOG_ERR, FALSE, + "unknown class \"%s\" at line %d in %s\n", + (const char *)$2, lineno, filename); + _exit(1); + } + $$ = c; + } + | string { + class *c = g_malloc(sizeof(class)); + c->name = $1; + c->list = NULL; + $$ = c; + } + ; + + +stringlist: string {$$ = g_slist_append(NULL, $1);} + | stringlist string {$$ = g_slist_append($1, $2);} + ; + +optstring: string {$$=$1;} + | /* empty */ {$$=NULL;} + ; + +string: STRING {$$=$1;} ; + +%% + +/* exported functions */ + +/* parse a file given by a name */ +void +parse_file(const char *name) { + FILE *infile; + + _pam_log(NULL, LOG_DEBUG, TRUE, "parsing config file %s", name); + infile = fopen(name, "r"); + if (!infile) { + _pam_log(NULL, LOG_ERR, FALSE, "could not parse required file %s", name); + return; + } + + if (!namespace) namespace = g_hash_table_new(g_str_hash, g_str_equal); + + lex_set_filename(name); + lex_file(infile); + + yyparse(); + fclose(infile); +} + +static int +check_one_console_name (const char *name, char *classComponent) { + regex_t p; + int r_err; + char *class_exp; + + class_exp = _do_malloc(strlen(classComponent) + 3); + sprintf(class_exp, "^%s$", classComponent); + r_err = regcomp(&p, class_exp, REG_EXTENDED|REG_NOSUB); + if (r_err) do_regerror(r_err, &p); + r_err = regexec(&p, name, 0, NULL, 0); + regfree(&p); + free (class_exp); + return !r_err; +} + +int +check_console_name (const char *consolename) { + GSList *this_class; + GSList *this_list; + class *c; + int found = 0; + + _pam_log(NULL, LOG_DEBUG, TRUE, "check console %s", consolename); + if (consoleNameCache != consolename) { + consoleNameCache = consolename; + if (consoleHash) g_hash_table_destroy(consoleHash); + consoleHash = g_hash_table_new(NULL, NULL); + } + for (this_class = consoleClassList; this_class; + this_class = this_class->next) { + c = this_class->data; + if (c->list) { + for (this_list = c->list; this_list; this_list = this_list->next) { + if (check_one_console_name(consolename, this_list->data)) { + g_hash_table_insert(consoleHash, c, c); + found = 1; + } + } + } else { + if (check_one_console_name(consolename, c->name)) { + g_hash_table_insert(consoleHash, c, c); + found = 1; + } + } + } + + if (found) + return 1; + + /* not found */ + _pam_log(NULL, LOG_INFO, TRUE, "did not find console %s", consolename); + if (consoleHash) { + g_hash_table_destroy(consoleHash); + consoleHash = NULL; + } + return 0; +} + +int +set_permissions(const char *consolename, const char *username, GSList *files) { + struct passwd *pwd; + config *c; + GSList *cl; + + if (!consoleNameCache || strcmp(consolename, consoleNameCache)) { + if (!check_console_name(consolename)) return -1; + } + + pwd = getpwnam(username); + if (pwd == NULL) { + _pam_log(NULL, LOG_ERR, FALSE, "getpwnam failed for \"%s\"", username); + return -1; + } + + for (cl = configList; cl; cl = cl->next) { + c = cl->data; + if (g_hash_table_lookup(consoleHash, c->console_class)) { + if (c->device_class->list) + chmod_files(c->mode, pwd->pw_uid, -1, NULL, c->device_class->list, files); + else + chmod_files(c->mode, pwd->pw_uid, -1, c->device_class->name, NULL, files); + } + } + return 0; +} + +int +reset_permissions(const char *consolename, GSList *files) { + struct passwd *pwd; + struct group *grp; + config *c; + GSList *cl; + + if (!consoleNameCache || strcmp(consolename, consoleNameCache)) { + if (!check_console_name(consolename)) return -1; + } + + for (cl = configList; cl; cl = cl->next) { + c = cl->data; + if (g_hash_table_lookup(consoleHash, c->console_class)) { + pwd = getpwnam(c->revert_owner ? c->revert_owner : "root"); + if (pwd == NULL) { + _pam_log(NULL, LOG_ERR, FALSE, "getpwnam failed for %s", + c->revert_owner ? c->revert_owner : "root"); + return -1; + } + grp = getgrnam(c->revert_group ? c->revert_group : "root"); + if (grp == NULL) { + _pam_log(NULL, LOG_ERR, FALSE, "getgrnam failed for %s", + c->revert_group ? c->revert_group : "root"); + return -1; + } + if (c->device_class->list) + chmod_files(c->revert_mode ? c->revert_mode : "0600", + pwd->pw_uid, grp->gr_gid, NULL, c->device_class->list, files); + else + chmod_files(c->revert_mode ? c->revert_mode : "0600", + pwd->pw_uid, grp->gr_gid, c->device_class->name, NULL, files); + } + } + return 0; +} + + + + +/* local, static functions */ + +static void +do_yyerror(const char *format, ...) { + va_list ap; + + va_start(ap, format); + openlog("pam_console", LOG_CONS|LOG_PID, LOG_AUTHPRIV); + vsyslog(LOG_PID|LOG_AUTHPRIV|LOG_ERR, format, ap); + va_end(ap); +} + +static void +empty_class(class *c) { + g_free(c->name); + c->name = NULL; + g_slist_free(c->list); + c->list = NULL; +} diff --git a/pam_console/handlers.c b/pam_console/handlers.c index e40868e..9e8d6a5 100644 --- a/pam_console/handlers.c +++ b/pam_console/handlers.c @@ -16,8 +16,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "../../_pam_aconf.h" +#include "config.h" #include +#include #include #include #include @@ -25,6 +26,12 @@ #include #include #include +#include +#include +#include + +#include "handlers.h" +#include "pam_console.h" enum types { UNKNOWN, LOCK, UNLOCK, CONSOLEDEVS }; enum flags { HF_LOGFAIL, HF_WAIT, HF_SETUID, HF_TTY, HF_USER, HF_PARAM }; @@ -39,7 +46,7 @@ struct console_handler { static struct console_handler *first_handler; -STATIC void +static void console_free_handlers (struct console_handler *handler) { if (handler != NULL) { console_free_handlers(handler->next); @@ -48,8 +55,8 @@ console_free_handlers (struct console_handler *handler) { } } -STATIC int -console_parse_handlers (const char *handlers_name) { +int +console_parse_handlers (pam_handle_t *pamh, const char *handlers_name) { FILE *fh; char linebuf[HANDLERS_MAXLINELEN+1]; int forget; @@ -59,7 +66,7 @@ console_parse_handlers (const char *handlers_name) { fh = fopen(handlers_name, "r"); if (fh == NULL) { - _pam_log(LOG_ERR, FALSE, "cannot open file %s for reading", handlers_name); + _pam_log(pamh, LOG_ERR, FALSE, "cannot open file %s for reading", handlers_name); return rv; } @@ -77,7 +84,7 @@ console_parse_handlers (const char *handlers_name) { len = strlen(linebuf); if (linebuf[len-1] != '\n') { - _pam_log(LOG_INFO, FALSE, "line too long or not ending with new line char - will be ignored"); + _pam_log(pamh, LOG_INFO, FALSE, "line too long or not ending with new line char - will be ignored"); skip = 1; continue; } @@ -194,7 +201,7 @@ call_exec(struct console_handler *handler, int nparams, const char *user, const } static int -execute_handler(struct console_handler *handler, const char *user, const char *tty) { +execute_handler(pam_handle_t *pamh, struct console_handler *handler, const char *user, const char *tty) { const char *flagptr; int nparams = 0; int logfail = 0; @@ -229,7 +236,7 @@ execute_handler(struct console_handler *handler, const char *user, const char *t child = fork(); switch (child) { case -1: - _pam_log(LOG_ERR, !logfail, "fork failed when executing handler '%s'", + _pam_log(pamh, LOG_ERR, !logfail, "fork failed when executing handler '%s'", handler->executable); return -1; case 0: @@ -270,30 +277,30 @@ execute_handler(struct console_handler *handler, const char *user, const char *t signal(SIGCHLD, sighandler); if (WIFEXITED(rv) && WEXITSTATUS(rv) != 0) - _pam_log(LOG_ERR, !logfail, "handler '%s' returned %d on exit", + _pam_log(pamh, LOG_ERR, !logfail, "handler '%s' returned %d on exit", handler->executable, (int)WEXITSTATUS(rv)); else if (WIFSIGNALED(rv)) - _pam_log(LOG_ERR, !logfail, "handler '%s' caught a signal %d", + _pam_log(pamh, LOG_ERR, !logfail, "handler '%s' caught a signal %d", handler->executable, (int)WTERMSIG(rv)); return 0; } -STATIC void -console_run_handlers(int lock, const char *user, const char *tty) { +void +console_run_handlers(pam_handle_t *pamh, int lock, const char *user, const char *tty) { struct console_handler *handler; for (handler = first_handler; handler != NULL; handler = handler->next) { if (lock && handler->type == LOCK) { - execute_handler(handler, user, tty); + execute_handler(pamh, handler, user, tty); } else if (!lock && handler->type == UNLOCK) { - execute_handler(handler, user, tty); + execute_handler(pamh, handler, user, tty); } } } -STATIC const char * +const char * console_get_regexes(void) { struct console_handler *handler; diff --git a/pam_console/handlers.h b/pam_console/handlers.h index b45bdcf..2ecc43b 100644 --- a/pam_console/handlers.h +++ b/pam_console/handlers.h @@ -5,14 +5,12 @@ #ifndef _HANDLERS_H #define _HANDLERS_H -#ifndef STATIC -#define STATIC -#endif +#include #define HANDLERS_MAXLINELEN 2000 -STATIC int console_parse_handlers (const char *filename); -STATIC void console_run_handlers(int lock, const char *user, const char *tty); -STATIC const char *console_get_regexes(void); +int console_parse_handlers (pam_handle_t *pamh, const char *filename); +void console_run_handlers(pam_handle_t *pamh, int lock, const char *user, const char *tty); +const char *console_get_regexes(void); #endif /* _HANDLERS_H */ diff --git a/pam_console/modechange.c b/pam_console/modechange.c index 799a13d..db0b7cc 100644 --- a/pam_console/modechange.c +++ b/pam_console/modechange.c @@ -30,7 +30,7 @@ changing the mode of many files, this probably results in a performance gain. */ -#include "../config.h" +#include "config.h" #include #include #include "modechange.h" @@ -72,7 +72,7 @@ oatoi (const char *s) representation of file mode change operations; return MODE_MEMORY_EXHAUSTED if there is insufficient memory. */ -struct mode_change * +STATIC struct mode_change * mode_compile (mode_string, masked_ops) const char *mode_string; unsigned masked_ops; @@ -241,7 +241,7 @@ invalid: change affects it even if no execute bits were set in OLDMODE. The returned value has the S_IFMT bits cleared. */ -unsigned short +STATIC unsigned short mode_adjust (oldmode, changes) unsigned oldmode; const struct mode_change *changes; @@ -308,7 +308,7 @@ mode_adjust (oldmode, changes) /* Free the memory used by the list of file mode change operations CHANGES. */ -void +STATIC void mode_free (changes) register struct mode_change *changes; { diff --git a/pam_console/pam_console.c b/pam_console/pam_console.c index d05e8af..a1e94c5 100644 --- a/pam_console/pam_console.c +++ b/pam_console/pam_console.c @@ -25,7 +25,7 @@ * and everything in /var/run/console/ */ -#include "../../_pam_aconf.h" +#include "config.h" #include #include #include @@ -34,18 +34,16 @@ #include #include #include -#include #include #include #include #include -#define STATIC static #include "pam_console.h" #include "handlers.h" - #include #include -#include +#include +#include /* In order to avoid errors in pam_get_item(), we need a very * unfortunate cast. This is a terrible design error in PAM @@ -63,17 +61,15 @@ static int allow_nonroot_tty = 0; /* some syslogging */ -static void -_pam_log(int err, int debug_p, const char *format, ...) +void +_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...) { va_list args; if (debug_p && !debug) return; va_start(args, format); - openlog("pam_console", LOG_CONS|LOG_PID, LOG_AUTHPRIV); - vsyslog(err, format, args); - va_end(args); + pam_vsyslog(pamh, err, format, args); closelog(); } @@ -87,10 +83,8 @@ _do_malloc(size_t req) return ret; } -#include "regerr.c" - static void -_args_parse(int argc, const char **argv) +_args_parse(pam_handle_t *pamh, int argc, const char **argv) { for (; argc-- > 0; ++argv) { if (!strcmp(*argv,"debug")) @@ -101,10 +95,10 @@ _args_parse(int argc, const char **argv) if (strlen(*argv+13) < PATH_MAX) strcpy(consolehandlers,*argv+13); else - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "_args_parse: handlersfile filename too long"); else { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "_args_parse: unknown option; %s",*argv); } } @@ -117,9 +111,9 @@ is_root(pam_handle_t *pamh, const char *username) { */ struct passwd *pwd; - pwd = _pammodutil_getpwnam(pamh, username); + pwd = pam_modutil_getpwnam(pamh, username); if (pwd == NULL) { - _pam_log(LOG_ERR, FALSE, "getpwnam failed for %s", username); + _pam_log(pamh, LOG_ERR, FALSE, "getpwnam failed for %s", username); return 0; } return !pwd->pw_uid; @@ -142,18 +136,18 @@ check_one_console_name(const char *name, const char *cregex) { } static int -check_console_name(const char *consolename, int nonroot_ok, int on_set) { +check_console_name(pam_handle_t *pamh, const char *consolename, int nonroot_ok, int on_set) { int found = 0; int statted = 0; struct stat st; char full_path[PATH_MAX]; const char *consoleregex; - _pam_log(LOG_DEBUG, TRUE, "check console %s", consolename); + _pam_log(pamh, LOG_DEBUG, TRUE, "check console %s", consolename); if ((consoleregex = console_get_regexes()) == NULL) { /* probably a broken configuration */ - _pam_log(LOG_INFO, FALSE, "no console regexes in console.handlers config"); + _pam_log(pamh, LOG_INFO, FALSE, "no console regexes in console.handlers config"); return 0; } for (; *consoleregex != '\0'; consoleregex += strlen(consoleregex)+1) { @@ -165,7 +159,7 @@ check_console_name(const char *consolename, int nonroot_ok, int on_set) { if (!found) { /* not found */ - _pam_log(LOG_INFO, TRUE, "no matching console regex found"); + _pam_log(pamh, LOG_INFO, TRUE, "no matching console regex found"); return 0; } @@ -174,7 +168,7 @@ check_console_name(const char *consolename, int nonroot_ok, int on_set) { memset(&st, 0, sizeof(st)); statted = 0; - _pam_log(LOG_DEBUG, TRUE, "checking possible console \"%s\"", consolename); + _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"", consolename); if (lstat(consolename, &st) != -1) { statted = 1; } @@ -183,14 +177,14 @@ check_console_name(const char *consolename, int nonroot_ok, int on_set) { strncat(full_path, consolename, sizeof(full_path) - 1 - strlen(full_path)); full_path[sizeof(full_path) - 1] = '\0'; - _pam_log(LOG_DEBUG, TRUE, "checking possible console \"%s\"", + _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"", full_path); if (lstat(full_path, &st) != -1) { statted = 1; } } if (!statted && (consolename[0] == ':')) { - size_t l; + int l; char *dot = NULL; strcpy(full_path, "/tmp/.X11-unix/X"); l = sizeof(full_path) - 1 - strlen(full_path); @@ -200,13 +194,13 @@ check_console_name(const char *consolename, int nonroot_ok, int on_set) { } strncat(full_path, consolename + 1, l); full_path[sizeof(full_path) - 1] = '\0'; - _pam_log(LOG_DEBUG, TRUE, "checking possible console \"%s\"", + _pam_log(pamh, LOG_DEBUG, TRUE, "checking possible console \"%s\"", full_path); if (lstat(full_path, &st) != -1) { statted = 1; } else if (!on_set) { /* there is no X11 socket in case of X11 crash */ - _pam_log(LOG_DEBUG, TRUE, "can't find X11 socket to examine for %s probably due to X crash", consolename); + _pam_log(pamh, LOG_DEBUG, TRUE, "can't find X11 socket to examine for %s probably due to X crash", consolename); statted = 1; /* this will work because st.st_uid is 0 */ } } @@ -214,19 +208,19 @@ check_console_name(const char *consolename, int nonroot_ok, int on_set) { if (statted) { int ok = 0; if (st.st_uid == 0) { - _pam_log(LOG_DEBUG, TRUE, "console %s is owned by UID 0", consolename); + _pam_log(pamh, LOG_DEBUG, TRUE, "console %s is owned by UID 0", consolename); ok = 1; } if (S_ISCHR(st.st_mode)) { - _pam_log(LOG_DEBUG, TRUE, "console %s is a character device", consolename); + _pam_log(pamh, LOG_DEBUG, TRUE, "console %s is a character device", consolename); ok = 1; } if (!ok && !nonroot_ok) { - _pam_log(LOG_INFO, TRUE, "%s is not a valid console device because it is owned by UID %d and the allow_nonroot flag was not set", consolename, st.st_uid); + _pam_log(pamh, LOG_INFO, TRUE, "%s is not a valid console device because it is owned by UID %d and the allow_nonroot flag was not set", consolename, st.st_uid); found = 0; } } else { - _pam_log(LOG_INFO, TRUE, "can't find device or X11 socket to examine for %s", consolename); + _pam_log(pamh, LOG_INFO, TRUE, "can't find device or X11 socket to examine for %s", consolename); found = 0; } @@ -234,22 +228,22 @@ check_console_name(const char *consolename, int nonroot_ok, int on_set) { return 1; /* not found */ - _pam_log(LOG_INFO, TRUE, "did not find console %s", consolename); + _pam_log(pamh, LOG_INFO, TRUE, "did not find console %s", consolename); return 0; } static int -lock_console(const char *id) +lock_console(pam_handle_t *pamh, const char *id) { int fd, ret_val; fd = open(consolelock, O_RDWR|O_CREAT|O_EXCL, 0600); if (fd < 0) { - _pam_log(LOG_INFO, TRUE, + _pam_log(pamh, LOG_INFO, TRUE, "console file lock already in place %s", consolelock); return -1; } - ret_val = _pammodutil_write (fd, id, strlen(id)); + ret_val = pam_modutil_write (fd, id, strlen(id)); if (ret_val == -1) { close(fd); } @@ -267,7 +261,7 @@ lock_console(const char *id) * If you can't stand goto, don't read this function. :-P */ static int -use_count(char *filename, int increment, int delete) +use_count(pam_handle_t *pamh, char *filename, int increment, int delete) { int fd, err, val; static int cache_fd = 0; @@ -283,7 +277,7 @@ use_count(char *filename, int increment, int delete) top: fd = open(filename, O_RDWR|O_CREAT, 0600); if (fd < 0) { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "Could not open lock file %s, disallowing console access", filename); return -1; @@ -311,7 +305,7 @@ top: * wait and calling fcntl again, not likely to ever happen, and * not a problem other than cosmetics even if it does. */ - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "ignoring stale lock on file %s by process %d", lockinfo.l_pid, filename); } @@ -329,20 +323,20 @@ top: if (fstat (fd, &st)) { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" fstat error on open fd for %s", filename); err = -1; goto return_error; } buf = _do_malloc(st.st_size+2); /* size will never grow by more than one */ if (st.st_size) { buf[0] = '\0'; /* if read returns eof, need atoi to give us 0 */ - if (_pammodutil_read (fd, buf, st.st_size) == -1) { - _pam_log(LOG_ERR, FALSE, + if (pam_modutil_read (fd, buf, st.st_size) == -1) { + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" read error on %s", filename); err = -1; goto return_error; } if (lseek(fd, 0, SEEK_SET) == -1) { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" lseek error on %s", filename); err = -1; goto return_error; } @@ -356,7 +350,7 @@ top: val += increment; if (val <= 0 && delete) { if (unlink (filename)) { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" unlink error on %s", filename); err = -1; goto return_error; } @@ -364,8 +358,8 @@ top: } sprintf(buf, "%d", val); - if (_pammodutil_write(fd, buf, strlen(buf)) == -1) { - _pam_log(LOG_ERR, FALSE, + if (pam_modutil_write(fd, buf, strlen(buf)) == -1) { + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" write error on %s", filename); err = -1; goto return_error; } @@ -398,7 +392,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) int ret = PAM_AUTH_ERR; D(("called.")); - _args_parse(argc, argv); + _args_parse(pamh, argc, argv); if (getuid() == 0) { /* Obtain user name by pam_get_user() . @@ -412,7 +406,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) ret = pam_get_item(pamh, PAM_RHOST, (const void **) &host); if (ret == PAM_SUCCESS && host && *host) { - _pam_log(LOG_ERR, TRUE, + _pam_log(pamh, LOG_ERR, TRUE, "PAM_RHOST is set - not invoked from console."); return PAM_AUTH_ERR; } @@ -424,26 +418,26 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) } ret = pam_get_user(pamh, &user, user_prompt); if (ret != PAM_SUCCESS) { - _pam_log(LOG_ERR, FALSE, "could not obtain user name"); + _pam_log(pamh, LOG_ERR, FALSE, "could not obtain user name"); return ret; } - pwd = _pammodutil_getpwnam(pamh, user); + pwd = pam_modutil_getpwnam(pamh, user); if (pwd == NULL) { - _pam_log(LOG_ERR, FALSE, "user '%s' unknown for this system", user); + _pam_log(pamh, LOG_ERR, FALSE, "user '%s' unknown for this system", user); return PAM_AUTH_ERR; } if (pwd->pw_uid == 0) { - _pam_log(LOG_ERR, TRUE, "user '%s' is not allowed to " + _pam_log(pamh, LOG_ERR, TRUE, "user '%s' is not allowed to " "authenticate by pam_console", pwd->pw_name); return PAM_AUTH_ERR; } } else { - pwd = _pammodutil_getpwuid(pamh, getuid()); + pwd = pam_modutil_getpwuid(pamh, getuid()); if (pwd == NULL) { - _pam_log(LOG_ERR, FALSE, "user with id %d not found", getuid()); + _pam_log(pamh, LOG_ERR, FALSE, "user with id %d not found", getuid()); return PAM_AUTH_ERR; } } @@ -456,13 +450,13 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) sprintf(appsfile, "%s%s", consoleapps, service); /* trusted data */ if (access(lockfile, F_OK) < 0) { - _pam_log(LOG_ERR, TRUE, + _pam_log(pamh, LOG_ERR, TRUE, "user %s not a console user", pwd->pw_name); ret = PAM_AUTH_ERR; goto error_return; } if (access(appsfile, F_OK) < 0) { - _pam_log(LOG_ERR, TRUE, + _pam_log(pamh, LOG_ERR, TRUE, "console access disallowed for service %s", service); ret = PAM_AUTH_ERR; goto error_return; } @@ -500,52 +494,52 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) const char *tty = NULL; D(("called.")); - _pam_log(LOG_ERR, TRUE, "pam_console open_session"); - _args_parse(argc, argv); + _pam_log(pamh, LOG_ERR, TRUE, "pam_console open_session"); + _args_parse(pamh, argc, argv); if(pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &user_prompt) != PAM_SUCCESS) { user_prompt = "user name: "; } username = NULL; pam_get_user(pamh, &username, user_prompt); - _pam_log(LOG_DEBUG, TRUE, "user is \"%s\"", + _pam_log(pamh, LOG_DEBUG, TRUE, "user is \"%s\"", username ? username : "(null)"); if (!username || !username[0]) { - _pam_log(LOG_DEBUG, TRUE, "user is \"%s\"", + _pam_log(pamh, LOG_DEBUG, TRUE, "user is \"%s\"", username ? username : "(null)"); return PAM_SESSION_ERR; } if (is_root(pamh, username)) { - _pam_log(LOG_DEBUG, TRUE, "user \"%s\" is root", username); + _pam_log(pamh, LOG_DEBUG, TRUE, "user \"%s\" is root", username); return PAM_SUCCESS; } pam_get_item(pamh, PAM_TTY, CAST_ME_HARDER &tty); if (!tty || !tty[0]) { - _pam_log(LOG_ERR, TRUE, "TTY not defined"); + _pam_log(pamh, LOG_ERR, TRUE, "TTY not defined"); return PAM_SESSION_ERR; } /* get configuration */ if (!configfileparsed) { - console_parse_handlers(consolehandlers); + console_parse_handlers(pamh, consolehandlers); configfileparsed = 1; } /* return success quietly if not a terminal login */ - if (!check_console_name(tty, allow_nonroot_tty, TRUE)) return PAM_SUCCESS; + if (!check_console_name(pamh, tty, allow_nonroot_tty, TRUE)) return PAM_SUCCESS; - if (!lock_console(username)) got_console = 1; + if (!lock_console(pamh, username)) got_console = 1; lockfile = _do_malloc(strlen(consolerefs) + strlen(username) + 2); sprintf(lockfile, "%s%s", consolerefs, username); /* trusted data */ - count = use_count(lockfile , 1, 0); + count = use_count(pamh, lockfile , 1, 0); if (count < 0) { ret = PAM_SESSION_ERR; } else if (got_console) { - _pam_log(LOG_DEBUG, TRUE, "%s is console user", username); + _pam_log(pamh, LOG_DEBUG, TRUE, "%s is console user", username); /* errors will be logged and are not critical */ - console_run_handlers(TRUE, username, tty); + console_run_handlers(pamh, TRUE, username, tty); } free(lockfile); @@ -575,7 +569,7 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) struct stat st; D(("called.")); - _args_parse(argc, argv); + _args_parse(pamh, argc, argv); if(pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &user_prompt) != PAM_SUCCESS) { user_prompt = "user name: "; @@ -589,16 +583,16 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) /* get configuration */ if (!configfileparsed) { - console_parse_handlers(consolehandlers); + console_parse_handlers(pamh, consolehandlers); configfileparsed = 1; } /* return success quietly if not a terminal login */ - if (!check_console_name(tty, allow_nonroot_tty, FALSE)) return PAM_SUCCESS; + if (!check_console_name(pamh, tty, allow_nonroot_tty, FALSE)) return PAM_SUCCESS; lockfile = _do_malloc(strlen(consolerefs) + strlen(username) + 2); sprintf(lockfile, "%s%s", consolerefs, username); /* trusted data */ - count = use_count(lockfile, 0, 0); + count = use_count(pamh, lockfile, 0, 0); if (count < 0) { err = PAM_SESSION_ERR; goto return_error; @@ -608,15 +602,15 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) fd = open(consolelock, O_RDONLY); if (fd != -1) { if (fstat (fd, &st)) { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" fstat error on %s", consolelock); close(fd); err = PAM_SESSION_ERR; goto return_error; } consoleuser = _do_malloc(st.st_size+1); if (st.st_size) { - if (_pammodutil_read (fd, consoleuser, st.st_size) == -1) { - _pam_log(LOG_ERR, FALSE, + if (pam_modutil_read (fd, consoleuser, st.st_size) == -1) { + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" read error on %s", consolelock); err = PAM_SESSION_ERR; close(fd); @@ -631,7 +625,7 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) /* errors will be logged and at this stage we cannot do * anything about them... */ - console_run_handlers(FALSE, username, tty); + console_run_handlers(pamh, FALSE, username, tty); } } else { /* didn't open file */ @@ -640,10 +634,10 @@ pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) } } - count = use_count(lockfile, -1, 1); + count = use_count(pamh, lockfile, -1, 1); if (count < 1 && delete_consolelock) { if (unlink(consolelock)) { - _pam_log(LOG_ERR, FALSE, + _pam_log(pamh, LOG_ERR, FALSE, "\"impossible\" unlink error on %s", consolelock); err = PAM_SESSION_ERR; goto return_error; } @@ -673,6 +667,3 @@ struct pam_module _pam_console_modstruct = { #endif /* end of module definition */ - -/* supporting functions included from other .c files... */ -#include "handlers.c" diff --git a/pam_console/pam_console.h b/pam_console/pam_console.h index 84c4c4b..5d92771 100644 --- a/pam_console/pam_console.h +++ b/pam_console/pam_console.h @@ -5,10 +5,14 @@ #ifndef _PAM_CONSOLE_H #define _PAM_CONSOLE_H #include +#include #define LOCKFILE "console.lock" -static void -_pam_log(int err, int debug_p, const char *format, ...); +void +_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...); + +void +do_regerror(int errcode, const regex_t *preg); #endif /* _PAM_CONSOLE_H */ diff --git a/pam_console/pam_console_apply.c b/pam_console/pam_console_apply.c index 1cca7aa..b506c15 100644 --- a/pam_console/pam_console_apply.c +++ b/pam_console/pam_console_apply.c @@ -2,7 +2,7 @@ * Read in the file, and grant ownerships to whoever has the lock. */ -#include "../../_pam_aconf.h" +#include "config.h" #include #include #include @@ -21,7 +21,7 @@ #define STATIC static #include "chmod.h" #include "pam_console.h" -#include "config.h" +#include "configfile.h" #include @@ -35,17 +35,8 @@ static char tty[PATH_MAX] = "tty0"; static int debug = 0; static int syslogging = 0; -static void * -_do_malloc(size_t req) -{ - void *ret; - ret = malloc(req); - if (!ret) abort(); - return ret; -} - -static void -_pam_log(int err, int debug_p, const char *format, ...) +void +_pam_log(pam_handle_t *pamh, int err, int debug_p, const char *format, ...) { va_list args; if (debug_p && !debug) return; @@ -152,7 +143,7 @@ main(int argc, char **argv) fd = open(consolelock, O_RDONLY); if (fd != -1) { if (fstat (fd, &st)) { - _pam_log(LOG_ERR, FALSE, + _pam_log(NULL, LOG_ERR, FALSE, "\"impossible\" fstat error on %s", consolelock); close(fd); goto return_error; @@ -161,7 +152,7 @@ main(int argc, char **argv) consoleuser = _do_malloc(st.st_size+1); memset(consoleuser, '\0', st.st_size); if ((i = read (fd, consoleuser, st.st_size)) == -1) { - _pam_log(LOG_ERR, FALSE, + _pam_log(NULL, LOG_ERR, FALSE, "\"impossible\" read error on %s", consolelock); goto return_error; @@ -183,11 +174,3 @@ main(int argc, char **argv) return_error: return 1; } - -/* supporting functions included from other .c files... */ - -#include "regerr.c" -#include "chmod.c" -#include "modechange.c" -#include "config.lex.c" -#include "config.tab.c" diff --git a/pam_console/regerr.c b/pam_console/regerr.c index b901ab8..a788dcd 100644 --- a/pam_console/regerr.c +++ b/pam_console/regerr.c @@ -2,14 +2,19 @@ * This software may be used under the terms of the GNU General Public * License, available in the file COPYING accompanying this file */ -#include "../config.h" -#include -#include +#include "config.h" #include -#include +#include +#include +#include +#include #include "pam_console.h" -void +#ifndef STATIC +#define STATIC +#endif + +STATIC void do_regerror(int errcode, const regex_t *preg) { char *errbuf; size_t errbuf_size; @@ -22,6 +27,6 @@ do_regerror(int errcode, const regex_t *preg) { } regerror(errcode, preg, errbuf, errbuf_size); - _pam_log(LOG_ERR, 0, + pam_syslog(NULL, LOG_ERR, "regular expression error %s", errbuf); } diff --git a/pam_console/sed-static b/pam_console/sed-static index c6d3ce5..b9a6fa2 100644 --- a/pam_console/sed-static +++ b/pam_console/sed-static @@ -14,7 +14,6 @@ sed ' /^YY_BUFFER_STATE yy_scan_string/s/^/STATIC / /^void yy_switch_to_buffer/s/^/STATIC / /define YY_DECL int yylex/s/YY_DECL /YY_DECL STATIC / -/^int$/s/^/STATIC / /^int yyparse/s/^/STATIC / /^void yyrestart/s/^/STATIC / ' < $1 > sedtmp.$$ && mv sedtmp.$$ $1 diff --git a/pam_localuser/README b/pam_localuser/README deleted file mode 100644 index b8cdf52..0000000 --- a/pam_localuser/README +++ /dev/null @@ -1,17 +0,0 @@ -pam_localuser: - Succeeds iff the PAM_USER is listed in /etc/passwd. This seems to be a - common policy need (allowing only a subset of network-wide users, and - any locally-defined users, to access services). Simpler than using - awk to generate a file for use with pam_listfile (-F: '{print $1}'), - I guess. - -RECOGNIZED ARGUMENTS: - debug write debugging messages to syslog - file=FILE scan FILE instead of /etc/passwd - -MODULE SERVICES PROVIDED: - auth,account scan the FILE (/etc/passwd by default) and return - a success code if an entry is found for the user - -AUTHOR: - Nalin Dahyabhai diff --git a/pam_localuser/pam_localuser.8 b/pam_localuser/pam_localuser.8 deleted file mode 100644 index ce0a946..0000000 --- a/pam_localuser/pam_localuser.8 +++ /dev/null @@ -1,36 +0,0 @@ -.\" Copyright 2000 Red Hat, Inc. -.TH pam_localuser 8 2000/7/21 "Red Hat" "System Administrator's Manual" - -.SH NAME -pam_localuser \- require users to be listed in /etc/passwd - -.SH SYNOPSIS -.B account sufficient /lib/security/pam_localuser.so \fIargs\fP -.br -.B account required /lib/security/pam_wheel.so group=devel - -.SH DESCRIPTION -pam_localuser.so exists to help implement site-wide login policies, where -they typically include a subset of the network's users and a few accounts -that are local to a particular workstation. Using pam_localuser.so and -pam_wheel.so or pam_listfile.so is an effective way to restrict access to -either local users and/or a subset of the network's users. - -This could also be implemented using pam_listfile.so and a very short awk -script invoked by cron, but it's common enough to have been separated out. - -.SH ARGUMENTS -.IP debug -turns on debugging -.IP file=\fBFILE\fP -uses a file other than \fB/etc/passwd\fP. - -.SH FILES -/etc/passwd - -.SH BUGS -Let's hope not, but if you find any, please report them via the "Bug Track" -link at http://bugzilla.redhat.com/bugzilla/ - -.SH AUTHOR -Nalin Dahyabhai diff --git a/pam_localuser/pam_localuser.c b/pam_localuser/pam_localuser.c deleted file mode 100644 index 24e1dad..0000000 --- a/pam_localuser/pam_localuser.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Copyright 2001, 2004 Red Hat, Inc. - * - * 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 "../../_pam_aconf.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define PAM_SM_AUTH -#define PAM_SM_ACCOUNT -#include "../../libpam/include/security/pam_modules.h" -#include "../../libpam/include/security/_pam_macros.h" - -#define MODULE_NAME "pam_localuser" - -PAM_EXTERN -int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - int i, ret = PAM_SUCCESS; - FILE *fp; - int debug = 0; - const char *filename = "/etc/passwd"; - char line[LINE_MAX], name[LINE_MAX]; - const char *user; - - /* process arguments */ - for(i = 0; i < argc; i++) { - if(strcmp("debug", argv[i]) == 0) { - debug = 1; - } - } - for(i = 0; i < argc; i++) { - if(strncmp("file=", argv[i], 5) == 0) { - filename = argv[i] + 5; - if(debug) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_DEBUG, "set filename to \"%s\"", - filename); - closelog(); - } - } - } - - /* open the file */ - fp = fopen(filename, "r"); - if(fp == NULL) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_ERR, "error opening \"%s\": %s", filename, - strerror(errno)); - closelog(); - return PAM_SYSTEM_ERR; - } - - if(pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_ERR, "user name not specified yet"); - closelog(); - fclose(fp); - return PAM_SYSTEM_ERR; - } - - if ((user == NULL) || (strlen(user) == 0)) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_ERR, "user name not valid"); - closelog(); - fclose(fp); - return PAM_SYSTEM_ERR; - } - - /* scan the file, using fgets() instead of fgetpwent() because i - * don't want to mess with applications which call fgetpwent() */ - ret = PAM_PERM_DENIED; - snprintf(name, sizeof(name), "%s:", user); - i = strlen(name); - while(fgets(line, sizeof(line), fp) != NULL) { - if(debug) { - openlog(MODULE_NAME, LOG_PID, LOG_AUTHPRIV); - syslog(LOG_DEBUG, "checking \"%s\"", line); - closelog(); - } - if(strncmp(name, line, i) == 0) { - ret = PAM_SUCCESS; - break; - } - } - - /* okay, we're done */ - fclose(fp); - return ret; -} - -PAM_EXTERN -int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -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_localuser_modstruct = { - "pam_localuser", - pam_sm_authenticate, - pam_sm_setcred, - pam_sm_acct_mgmt, - NULL, - NULL, - NULL, -}; - -#endif diff --git a/pam_loginuid/Makefile b/pam_loginuid/Makefile deleted file mode 100644 index 398655b..0000000 --- a/pam_loginuid/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# $Id$ -# - -include ../../Make.Rules - -TITLE=pam_loginuid -MAN8=$(TITLE).8 - -include ../Simple.Rules - diff --git a/pam_loginuid/Makefile.am b/pam_loginuid/Makefile.am new file mode 100644 index 0000000..c95fb64 --- /dev/null +++ b/pam_loginuid/Makefile.am @@ -0,0 +1,21 @@ +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# + +CLEANFILES = *~ + +man_MANS = pam_loginuid.8 +EXTRA_DIST = README $(man_MANS) + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam +if HAVE_VERSIONING + AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif + +securelib_LTLIBRARIES = pam_loginuid.la diff --git a/pam_loginuid/pam_loginuid.c b/pam_loginuid/pam_loginuid.c index 748b7a1..af43f72 100644 --- a/pam_loginuid/pam_loginuid.c +++ b/pam_loginuid/pam_loginuid.c @@ -22,6 +22,7 @@ * PAM module that sets the login uid introduced in kernel 2.6.11 */ +#include "config.h" #include #include #include @@ -32,29 +33,17 @@ #include #include -#include +#include +#include -#define __USE_GNU #include -#undef __USE_GNU -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("pam_loginuid", LOG_CONS|LOG_PID, LOG_AUTH); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - /* * This function writes the loginuid to the /proc system. It returns * 0 on success and 1 on failure. */ -static int set_loginuid(uid_t uid) +static int set_loginuid(pam_handle_t *pamh, uid_t uid) { int fd, count, rc = 0; char loginuid[16]; @@ -67,10 +56,10 @@ static int set_loginuid(uid_t uid) rc = 1; loglevel = LOG_ERR; } - _pam_log(loglevel, "set_loginuid failed opening loginuid\n"); + pam_syslog(pamh, loglevel, "set_loginuid failed opening loginuid"); return rc; } - if (_pammodutil_write(fd, loginuid, count) != count) + if (pam_modutil_write(fd, loginuid, count) != count) rc = 1; close(fd); return rc; @@ -88,19 +77,19 @@ _pam_loginuid(pam_handle_t *pamh, int flags, int argc, const char **argv) /* get user name */ if (pam_get_item(pamh, PAM_USER, (const void **) &user) != PAM_SUCCESS) { - _pam_log(LOG_ERR, "error recovering login user-name"); + pam_syslog(pamh, LOG_ERR, "error recovering login user-name"); return PAM_SESSION_ERR; } /* get user info */ if ((pwd = getpwnam(user)) == NULL) { - _pam_log(LOG_ERR, + pam_syslog(pamh, LOG_ERR, "error: login user-name '%s' does not exist", user); return PAM_SESSION_ERR; } - if (set_loginuid(pwd->pw_uid)) { - _pam_log(LOG_ERR, "set_loginuid failed\n"); + if (set_loginuid(pamh, pwd->pw_uid)) { + pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n"); return PAM_SESSION_ERR; } diff --git a/pam_postgresok/Makefile.am b/pam_postgresok/Makefile.am index f096303..2f57057 100644 --- a/pam_postgresok/Makefile.am +++ b/pam_postgresok/Makefile.am @@ -1,9 +1,21 @@ -include ../Makefile-module.am +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# -EXTRA_DIST = pam_postgresok.8 +CLEANFILES = *~ -module_LTLIBRARIES = pam_postgresok.la -pam_postgresok_la_SOURCES = pam_postgresok.c -pam_postgresok_la_LIBADD = ../lib/libmisc.la -pam_postgresok_la_LDFLAGS = $(MODULE_LDFLAGS) -man8_MANS = pam_postgresok.8 +man_MANS = pam_postgresok.8 +EXTRA_DIST = README $(man_MANS) + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam +if HAVE_VERSIONING + AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif + +securelib_LTLIBRARIES = pam_postgresok.la diff --git a/pam_postgresok/pam_postgresok.c b/pam_postgresok/pam_postgresok.c index 7e9b727..7ef5a33 100644 --- a/pam_postgresok/pam_postgresok.c +++ b/pam_postgresok/pam_postgresok.c @@ -6,8 +6,9 @@ * written by Andrew Morgan 1996/3/11 */ -#include "../config.h" -#include "../lib/libmisc.h" +#define _GNU_SOURCE + +#include "config.h" #include #include #include @@ -25,26 +26,14 @@ #define PAM_SM_AUTH #include - -/* some syslogging */ - -static void _pam_log(int err, const char *format, ...) -{ - va_list args; - - va_start(args, format); - openlog("PAM-postgresok", LOG_CONS|LOG_PID, LOG_AUTHPRIV); - vsyslog(err, format, args); - va_end(args); - closelog(); -} - +#include +#include /* argument parsing */ #define PAM_DEBUG_ARG 01 -static int _pam_parse(int argc, const char **argv) +static int _pam_parse(pam_handle_t *pamh, int argc, const char **argv) { int ctrl=0; @@ -56,7 +45,7 @@ static int _pam_parse(int argc, const char **argv) if (!strcmp(*argv,"debug")) ctrl |= PAM_DEBUG_ARG; else { - _pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv); + pam_syslog(pamh, LOG_ERR,"pam_parse: unknown option; %s",*argv); } } @@ -74,16 +63,16 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc int ctrl; int retval = PAM_AUTH_ERR; - ctrl = _pam_parse(argc, argv); + ctrl = _pam_parse(pamh, argc, argv); uid = getuid(); - pw = libmisc_getpwuid(pamh, uid); + pw = pam_modutil_getpwuid(pamh, uid); if ((uid == 26) && (pw != NULL) && (strcmp(pw->pw_name, "postgres") == 0)) retval = PAM_SUCCESS; if (ctrl & PAM_DEBUG_ARG) { - _pam_log(LOG_DEBUG, "authentication %s" + pam_syslog(pamh, LOG_DEBUG, "authentication %s" , retval==PAM_SUCCESS ? "succeeded":"failed" ); } diff --git a/pam_rps/Makefile.am b/pam_rps/Makefile.am index 084b7b3..756d68b 100644 --- a/pam_rps/Makefile.am +++ b/pam_rps/Makefile.am @@ -1,8 +1,21 @@ -include ../Makefile-module.am +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# -EXTRA_DIST = pam_rps.8 +CLEANFILES = *~ -module_LTLIBRARIES = pam_rps.la -pam_rps_la_SOURCES = pam_rps.c -pam_rps_la_LDFLAGS = $(MODULE_LDFLAGS) -man8_MANS = pam_rps.8 +man_MANS = pam_rps.8 +EXTRA_DIST = README $(man_MANS) + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam +if HAVE_VERSIONING + AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif + +securelib_LTLIBRARIES = pam_rps.la diff --git a/pam_stack/Makefile.am b/pam_stack/Makefile.am index 246dfb3..234d518 100644 --- a/pam_stack/Makefile.am +++ b/pam_stack/Makefile.am @@ -1,9 +1,21 @@ -EXTRA_DIST = pam_stack.8 +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# -include ../Makefile-module.am +CLEANFILES = *~ -module_LTLIBRARIES = pam_stack.la -pam_stack_la_CFLAGS = -I$(PAMSRCDIR) @LAUS_CFLAGS@ -pam_stack_la_SOURCES = pam_stack.c -pam_stack_la_LDFLAGS = $(MODULE_LDFLAGS) @LAUS_LIBS@ -man8_MANS = pam_stack.8 +man_MANS = pam_stack.8 +EXTRA_DIST = README $(man_MANS) + +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam +if HAVE_VERSIONING + AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif + +securelib_LTLIBRARIES = pam_stack.la diff --git a/pam_stack/pam_stack.c b/pam_stack/pam_stack.c index 51938c9..58b4cf6 100644 --- a/pam_stack/pam_stack.c +++ b/pam_stack/pam_stack.c @@ -46,10 +46,10 @@ #define PAM_CONST const -#include "../../_pam_aconf.h" -#include "../../libpam/include/security/_pam_types.h" +#include "config.h" +#include #include "../../libpam/pam_private.h" -#include +#include #include #include @@ -338,12 +338,8 @@ _pam_stack_dispatch(pam_handle_t *pamh, int flags, int argc, const char **argv, } /* Sign-on message. */ - if(debug) { - openlog("pam_stack", LOG_PID, LOG_AUTHPRIV); - syslog(LOG_DEBUG, "called from \"%s\"", - parent_service ? parent_service : "unknown service"); - closelog(); - } + syslog(LOG_WARNING|LOG_AUTHPRIV, "Deprecated pam_stack module called from service \"%s\"", + parent_service ? parent_service : "unknown service"); if(service == NULL) { openlog("pam_stack", LOG_PID, LOG_AUTHPRIV); syslog(LOG_ERR, "required argument \"service\" not given"); diff --git a/pam_succeed_if/README b/pam_succeed_if/README deleted file mode 100644 index 5c96795..0000000 --- a/pam_succeed_if/README +++ /dev/null @@ -1,67 +0,0 @@ -pam_succeed_if: - Succeed or fail based on account characteristics. - - pam_succeed_if.so is designed to succeed or fail authentication based - on characteristics of the account belonging to the user being - authenticated. - - The module can be given one or more conditions as module arguments, and - authentication will succeed only if all of the conditions are met. - - Conditions are expressed in the form - - ATTRIBUTE OPERATOR VALUE - - Recognized attributes: - - LOGIN - The user's login name. - UID - The user's UID. - GID - The user's primary GID. - SHELL - The user's shell. - HOME - The user's home directory. - - Recognized operators: - - < - Arithmetic less-than. - <= - Arithmetic less-than-or-equal-to. - > - Arithmetic greater-than. - >= - Arithmetic greater-than-or-equal-to. - eq - Arithmetic equality. - = - String equality. - ne - Arithmetic inequality. - != - String inequality. - =~ - Wildcard match. - !~ - Wildcard mismatch. - ingroup - Group membership check. [*] - notingroup - Group non-membership check. [*] - owns - File ownership check. [*] - - * These operators should only be used with the USER attribute. - - Examples: - - Deny authentication to all users except those in the wheel - group, before even asking for a password: - auth requisite pam_succeed_if.so user ingroup wheel - - Assume all users with UID less than 500 ("system users") have - valid accounts. - account sufficient pam_succeed_if.so uid < 500 - - Deny login to all nologin users. - auth requisite pam_succeed_if.so shell =~ nologin - -RECOGNIZED ARGUMENTS: - debug write debugging messages to syslog - use_uid perform checks on the account of the user under whose - UID the application is running instead of the user - being authenticated - quiet_success don't log condition successes - quiet_failure don't log condition failures - quiet don't log either condition successes or failures - -MODULE SERVICES PROVIDED: - authentication, account management - -AUTHOR: - Nalin Dahyabhai diff --git a/pam_succeed_if/pam_succeed_if.8 b/pam_succeed_if/pam_succeed_if.8 deleted file mode 100644 index 2dec43a..0000000 --- a/pam_succeed_if/pam_succeed_if.8 +++ /dev/null @@ -1,30 +0,0 @@ -.\" Copyright 2003 Red Hat, Inc. -.\" Written by Nalin Dahyabhai -.TH pam_succeed_if 8 2003/6/30 "Red Hat Linux" "System Administrator's Manual" - -.SH NAME -pam_succeed_if \- succeed or fail based on account characteristics - -.SH SYNOPSIS -.B account sufficient pam_succeed_if.so uid < 500 - -.SH DESCRIPTION -pam_succeed_if.so is designed to succeed or fail authentication based on -characteristics of the account belonging to the user being authenticated. - -The module can be given one or more conditions as module arguments, and -authentication will succeed only if all of the conditions are met. - -.SH ARGUMENTS -.IP debug -Turns on debugging messages sent to syslog. -.IP use_uid -Evaluate conditions using the account of the user whose UID the application -is running under instead of the user being authenticated. - -.SH BUGS -Let's hope not, but if you find any, please report them via the "Bug Track" -link at http://bugzilla.redhat.com/bugzilla/ - -.SH AUTHOR -Nalin Dahyabhai diff --git a/pam_succeed_if/pam_succeed_if.c b/pam_succeed_if/pam_succeed_if.c deleted file mode 100644 index 29c5e39..0000000 --- a/pam_succeed_if/pam_succeed_if.c +++ /dev/null @@ -1,520 +0,0 @@ -/****************************************************************************** - * A simple user-attribute based module for PAM. - * - * Copyright (c) 2003,2004 Red Hat, Inc. - * Written by Nalin Dahyabhai - * - * 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. - * - */ - -#ident "$Id$" - -#include "../config.h" -#include "../lib/libmisc.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MODULE "pam_succeed_if" - -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); - } - va_end(va); -} - -/* 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. */ -static int -evaluate_num(const char *left, const char *right, int (*cmp)(int, int)) -{ - long l, r; - char *p; - int ret = PAM_SUCCESS; - - l = strtol(left, &p, 0); - if ((p == NULL) || (*p != '\0')) { - log_error(LOG_INFO, "\"%s\" is not a number", left); - ret = PAM_SERVICE_ERR; - } - - r = strtol(right, &p, 0); - if ((p == NULL) || (*p != '\0')) { - log_error(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 char *left, const char *right) -{ - return evaluate_num(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 char *left, const char *right) -{ - return evaluate_num(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 char *left, const char *right) -{ - return evaluate_num(left, right, lt); -} -/* Test for numeric less-than-or-equal-ness(?) */ -static int -evaluate_le(const char *left, const char *right) -{ - return evaluate_num(left, right, le); -} -/* Test for numeric greater-than-ness(?) */ -static int -evaluate_gt(const char *left, const char *right) -{ - return evaluate_num(left, right, gt); -} -/* Test for numeric greater-than-or-equal-ness(?) */ -static int -evaluate_ge(const char *left, const char *right) -{ - return evaluate_num(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; -} -/* 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 = libmisc_user_in_group_nam_nam(pamh, user, group); - switch (ret) { - case 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 = libmisc_user_in_group_nam_nam(pamh, user, group); - switch (ret) { - case 0: - return PAM_SUCCESS; - break; - default: - break; - } - return PAM_AUTH_ERR; -} -/* Return PAM_SUCCESS if the user owns the indicated file. */ -static int -evaluate_owns(pam_handle_t *pamh, const char *user, const char *path) -{ - struct stat st; - struct passwd *pwd; - if (lstat(path, &st) == 0) { - pwd = libmisc_getpwnam(pamh, user); - if (pwd != NULL) { - if (st.st_uid == pwd->pw_uid) { - 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, gid_t *grouplist, size_t grlistlen) -{ - 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 we have no idea what's going on, return an error. */ - if (left != buf) { - log_error(LOG_CRIT, "unknown attribute \"%s\"", left); - return PAM_SERVICE_ERR; - } - if (debug) { - log_error(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); - } - /* Attribute value <= some threshold. */ - if ((strcasecmp(qual, "<=") == 0) || - (strcasecmp(qual, "le") == 0)) { - return evaluate_le(left, right); - } - /* Attribute value > some threshold. */ - if ((strcasecmp(qual, ">") == 0) || - (strcasecmp(qual, "gt") == 0)) { - return evaluate_gt(left, right); - } - /* Attribute value >= some threshold. */ - if ((strcasecmp(qual, ">=") == 0) || - (strcasecmp(qual, "ge") == 0)) { - return evaluate_ge(left, right); - } - /* Attribute value == some threshold. */ - if (strcasecmp(qual, "eq") == 0) { - return evaluate_eqn(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(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); - } - /* 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); - } - /* User owns the named file. */ - if (strcasecmp(qual, "owns") == 0) { - return evaluate_owns(pamh, 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) -{ - const char *prompt; - const char *user; - struct passwd *pwd; - gid_t *grouplist = NULL; - int grlistlen = 2; - int ret, i, debug, quiet_success, quiet_failure, use_uid; - const char *left, *right, *qual; - - /* Get the user prompt. */ - ret = libmisc_get_string_item(pamh, PAM_USER_PROMPT, &prompt); - if ((ret != PAM_SUCCESS) || (prompt == NULL) || (strlen(prompt) == 0)) { - prompt = "login: "; - } - - debug = 0; - quiet_failure = 0; - quiet_success = 0; - use_uid = 0; - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug++; - } - if (strcmp(argv[i], "quiet_success") == 0) { - quiet_success++; - } - if (strcmp(argv[i], "quiet_failure") == 0) { - quiet_failure++; - } - if (strcmp(argv[i], "quiet") == 0) { - quiet_success++; - quiet_failure++; - } - if (strcmp(argv[i], "use_uid") == 0) { - use_uid++; - } - } - - if (use_uid) { - /* Get information about the user. */ - pwd = libmisc_getpwuid(pamh, getuid()); - if (pwd == NULL) { - log_error(LOG_CRIT, - "error retrieving information about user %ld", - (long)getuid()); - return PAM_SERVICE_ERR; - } - } 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)); - return ret; - } - - /* Get information about the user. */ - pwd = libmisc_getpwnam(pamh, user); - if (pwd == NULL) { - log_error(LOG_CRIT, - "error retrieving information about user %s", - user); - return PAM_SERVICE_ERR; - } - } - - /* Get the user's supplemental group list. */ - grlistlen = 2; - do { - grouplist = malloc(sizeof(gid_t) * grlistlen); - ret = getgrouplist(pwd->pw_name, pwd->pw_gid, - grouplist, &grlistlen); - if (ret == -1) { - free(grouplist); - grlistlen *= 2; - } - } while (ret == -1); - if ((ret == -1) || (grlistlen < 0)) { - log_error(LOG_CRIT, - "error retrieving group list for user %s", user); - return PAM_SERVICE_ERR; - } - - /* Walk the argument list. */ - i = 0; - left = qual = right = NULL; - while (i <= argc) { - if ((left != NULL) && (qual != NULL) && (right != NULL)) { - ret = evaluate(pamh, debug, - left, qual, right, - pwd, grouplist, grlistlen); - if (ret == PAM_SUCCESS) { - if (!quiet_success) { - log_error(LOG_INFO, - "requirement \"%s %s %s\" " - "met by user \"%s\"", - left, qual, right, user); - } else - if (debug) { - log_error(LOG_DEBUG, - "requirement \"%s %s %s\" " - "met by user \"%s\"", - left, qual, right, user); - } - } else { - if (!quiet_failure) { - log_error(LOG_INFO, - "requirement \"%s %s %s\" " - "not met by user \"%s\"", - left, qual, right, user); - } else - if (debug) { - log_error(LOG_DEBUG, - "requirement \"%s %s %s\" " - "not met by user \"%s\"", - left, qual, right, user); - } - break; - } - left = qual = right = NULL; - } - if ((i < argc) && (strcmp(argv[i], "debug") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_failure") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet_success") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "quiet") == 0)) { - i++; - continue; - } - if ((i < argc) && (strcmp(argv[i], "use_uid") == 0)) { - i++; - continue; - } - if ((i < argc) && (left == NULL)) { - left = argv[i++]; - continue; - } - if ((i < argc) && (qual == NULL)) { - qual = argv[i++]; - continue; - } - if ((i < argc) && (right == NULL)) { - right = argv[i++]; - continue; - } - i++; - } - - return ret; -} - -int -pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return PAM_SUCCESS; -} - -int -pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - return pam_sm_authenticate(pamh, flags, argc, argv); -} diff --git a/pam_timestamp/Makefile.am b/pam_timestamp/Makefile.am index 1398d0a..4475d47 100644 --- a/pam_timestamp/Makefile.am +++ b/pam_timestamp/Makefile.am @@ -1,29 +1,38 @@ -include ../Makefile-module.am +# +# Copyright (c) 2005 Thorsten Kukuk +# Copyright (c) 2005 Red Hat, Inc. +# -EXTRA_DIST = pam_timestamp.8 +CLEANFILES = *~ -noinst_LTLIBRARIES = libhmac.la -libhmac_la_SOURCES = \ - hmacsha1.c \ - hmacsha1.h \ - sha1.c \ - sha1.h \ - sha1sum.c +man_MANS = pam_timestamp.8 pam_timestamp_check.8 +EXTRA_DIST = README $(man_MANS) -module_LTLIBRARIES = pam_timestamp.la -pam_timestamp_la_SOURCES = pam_timestamp.c -pam_timestamp_la_LDFLAGS = $(MODULE_LDFLAGS) -pam_timestamp_la_LIBADD = libhmac.la ../lib/libmisc.la +securelibdir = $(SECUREDIR) +secureconfdir = $(SCONFIGDIR) +noinst_HEADERS = hmacsha1.h + +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_LDFLAGS = -no-undefined -avoid-version -module \ + -L$(top_builddir)/libpam -lpam + +pam_timestamp_la_LDFLAGS = -no-undefined -avoid-version -module +if HAVE_VERSIONING + pam_timestamp_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +endif + +securelib_LTLIBRARIES = pam_timestamp.la sbin_PROGRAMS = pam_timestamp_check -pam_timestamp_check_SOURCES = pam_timestamp_check.c -pam_timestamp_check_LDADD = libhmac.la ../lib/libmisc.la -EXTRA_PROGRAMS = hmactest hmacfile -hmactest_CFLAGS = @OPENSSL_CFLAGS@ +pam_timestamp_la_SOURCES = pam_timestamp.c hmacsha1.c sha1.c hmacsha1.h +pam_timestamp_la_CFLAGS = $(AM_CFLAGS) + +pam_timestamp_check_SOURCES = pam_timestamp_check.c hmacsha1.c sha1.c hmacsha1.h + +hmacfile_SOURCES = hmacfile.c hmacsha1.c sha1.c hmacsha1.h + hmactest_SOURCES = hmactest.c -hmactest_LDADD = libhmac.la ../lib/libmisc.la @OPENSSL_LIBS@ -hmacfile_SOURCES = hmacfile.c -hmacfile_LDADD = libhmac.la ../lib/libmisc.la +hmactest_LDADD = -lcrypto -man8_MANS = pam_timestamp.8 +noinst_PROGRAMS = hmacfile hmactest diff --git a/pam_timestamp/pam_timestamp.c b/pam_timestamp/pam_timestamp.c index 356bea8..1d35717 100644 --- a/pam_timestamp/pam_timestamp.c +++ b/pam_timestamp/pam_timestamp.c @@ -41,7 +41,7 @@ #define PAM_SM_AUTH #define PAM_SM_SESSION -#include "../../_pam_aconf.h" +#include "config.h" #include #include @@ -56,12 +56,13 @@ #include #include #include +#include #include "hmacsha1.h" -#include "../../_pam_aconf.h" #include #include -#include +#include +#include /* The default timeout we use is 5 minutes, which matches the sudo default * for the timestamp_timeout parameter. */ @@ -80,7 +81,7 @@ /* Return PAM_SUCCESS if the given directory looks "safe". */ static int -check_dir_perms(const char *tdir) +check_dir_perms(pam_handle_t *pamh, const char *tdir) { char scratch[BUFLEN]; struct stat st; @@ -97,38 +98,38 @@ check_dir_perms(const char *tdir) /* We now have the name of a directory in the path, so * we need to check it. */ if ((lstat(scratch, &st) == -1) && (errno != ENOENT)) { - syslog(LOG_ERR, - MODULE ": unable to read `%s'", + pam_syslog(pamh, LOG_ERR, + "unable to read `%s': %m", scratch); return PAM_AUTH_ERR; } if (!S_ISDIR(st.st_mode)) { - syslog(LOG_ERR, - MODULE ": `%s' is not a directory", + pam_syslog(pamh, LOG_ERR, + "`%s' is not a directory", scratch); return PAM_AUTH_ERR; } if (S_ISLNK(st.st_mode)) { - syslog(LOG_ERR, - MODULE ": `%s' is a symbolic link", + pam_syslog(pamh, LOG_ERR, + "`%s' is a symbolic link", scratch); return PAM_AUTH_ERR; } if (st.st_uid != 0) { - syslog(LOG_ERR, - MODULE ": `%s' owner UID != 0", + pam_syslog(pamh, LOG_ERR, + "`%s' owner UID != 0", scratch); return PAM_AUTH_ERR; } if (st.st_gid != 0) { - syslog(LOG_ERR, - MODULE ": `%s' owner GID != 0", + pam_syslog(pamh, LOG_ERR, + "`%s' owner GID != 0", scratch); return PAM_AUTH_ERR; } if ((st.st_mode & (S_IWGRP | S_IWOTH)) != 0) { - syslog(LOG_ERR, - MODULE ": `%s' permissions are lax", + pam_syslog(pamh, LOG_ERR, + "`%s' permissions are lax", scratch); return PAM_AUTH_ERR; } @@ -231,7 +232,7 @@ get_ruser(pam_handle_t *pamh, char *ruserbuf, int ruserbuflen) } if ((ruser == NULL) || (strlen(ruser) == 0)) { /* Barring that, use the current RUID. */ - pwd = _pammodutil_getpwuid(pamh, getuid()); + pwd = pam_modutil_getpwuid(pamh, getuid()); if (pwd != NULL) { ruser = pwd->pw_name; } @@ -265,13 +266,13 @@ get_timestamp_name(pam_handle_t *pamh, int argc, const char **argv, if (strncmp(argv[i], "timestampdir=", 13) == 0) { tdir = argv[i] + 13; if (debug) { - syslog(LOG_DEBUG, - MODULE ": storing timestamps in `%s'", + pam_syslog(pamh, LOG_DEBUG, + "storing timestamps in `%s'", tdir); } } } - i = check_dir_perms(tdir); + i = check_dir_perms(pamh, tdir); if (i != PAM_SUCCESS) { return i; } @@ -286,14 +287,14 @@ get_timestamp_name(pam_handle_t *pamh, int argc, const char **argv, return PAM_AUTH_ERR; } if (debug) { - syslog(LOG_DEBUG, MODULE ": becoming user `%s'", user); + pam_syslog(pamh, LOG_DEBUG, "becoming user `%s'", user); } /* Get the name of the source user. */ if (get_ruser(pamh, ruser, sizeof(ruser)) || strlen(ruser) == 0) { return PAM_AUTH_ERR; } if (debug) { - syslog(LOG_DEBUG, MODULE ": currently user `%s'", ruser); + pam_syslog(pamh, LOG_DEBUG, "currently user `%s'", ruser); } /* Get the name of the terminal. */ if (pam_get_item(pamh, PAM_TTY, (const void**)&tty) != PAM_SUCCESS) { @@ -313,7 +314,7 @@ get_timestamp_name(pam_handle_t *pamh, int argc, const char **argv, } } if (debug) { - syslog(LOG_DEBUG, MODULE ": tty is `%s'", tty); + pam_syslog(pamh, LOG_DEBUG, "tty is `%s'", tty); } /* Snip off all but the last part of the tty name. */ tty = check_tty(tty); @@ -326,7 +327,7 @@ get_timestamp_name(pam_handle_t *pamh, int argc, const char **argv, return PAM_AUTH_ERR; } if (debug) { - syslog(LOG_DEBUG, MODULE ": using timestamp file `%s'", path); + pam_syslog(pamh, LOG_DEBUG, "using timestamp file `%s'", path); } return PAM_SUCCESS; } @@ -348,13 +349,13 @@ verbose_success(pam_handle_t *pamh, int debug, int diff) "Access granted (last access was %d " "seconds ago).", diff); message.msg = text; - syslog(LOG_DEBUG, MODULE ": %s", message.msg); + pam_syslog(pamh, LOG_DEBUG, "%s", message.msg); conv->conv(1, messages, &responses, conv->appdata_ptr); } else { - syslog(LOG_DEBUG, MODULE ": bogus conversation function"); + pam_syslog(pamh, LOG_DEBUG, "bogus conversation function"); } } else { - syslog(LOG_DEBUG, MODULE ": no conversation function"); + pam_syslog(pamh, LOG_DEBUG, "no conversation function"); } } @@ -381,8 +382,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) if ((p != NULL) && (*p == '\0')) { interval = tmp; if (debug) { - syslog(LOG_DEBUG, - MODULE ": setting timeout to %ld" + pam_syslog(pamh, LOG_DEBUG, + "setting timeout to %ld" " seconds", (long)interval); } } @@ -390,8 +391,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) if (strcmp(argv[i], "verbose") == 0) { verbose = 1; if (debug) { - syslog(LOG_DEBUG, - MODULE ": becoming more verbose"); + pam_syslog(pamh, LOG_DEBUG, + "becoming more verbose"); } } } @@ -414,9 +415,9 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) fd = open(path, O_RDONLY | O_NOFOLLOW); if (fd == -1) { if (debug) { - syslog(LOG_DEBUG, - MODULE ": cannot open timestamp `%s': %s", - path, strerror(errno)); + pam_syslog(pamh, LOG_DEBUG, + "cannot open timestamp `%s': %m", + path); } return PAM_AUTH_ERR; } @@ -429,7 +430,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) /* Check that the file is owned by the superuser. */ if ((st.st_uid != 0) || (st.st_gid != 0)) { - syslog(LOG_ERR, MODULE ": timestamp file `%s' is " + pam_syslog(pamh, LOG_ERR, "timestamp file `%s' is " "not owned by root", path); close(fd); return PAM_AUTH_ERR; @@ -437,7 +438,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) /* Check that the file is a normal file. */ if (!(S_ISREG(st.st_mode))) { - syslog(LOG_ERR, MODULE ": timestamp file `%s' is " + pam_syslog(pamh, LOG_ERR, "timestamp file `%s' is " "not a regular file", path); close(fd); return PAM_AUTH_ERR; @@ -451,7 +452,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) } if (st.st_size != strlen(path) + 1 + sizeof(then) + hmac_sha1_size()) { - syslog(LOG_NOTICE, MODULE ": timestamp file `%s' " + pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' " "appears to be corrupted", path); close(fd); return PAM_AUTH_ERR; @@ -472,8 +473,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) count += i; } if (count < st.st_size) { - syslog(LOG_NOTICE, MODULE ": error reading timestamp " - "file `%s'", path); + pam_syslog(pamh, LOG_NOTICE, "error reading timestamp " + "file `%s': %m", path); close(fd); free(message); return PAM_AUTH_ERR; @@ -486,7 +487,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) if ((mac == NULL) || (memcmp(path, message, strlen(path)) != 0) || (memcmp(mac, message_end, maclen) != 0)) { - syslog(LOG_NOTICE, MODULE ": timestamp file `%s' is " + pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is " "corrupted", path); close(fd); free(message); @@ -504,7 +505,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) } if (check_login_time(ruser, then) != PAM_SUCCESS) { - syslog(LOG_NOTICE, MODULE ": timestamp file `%s' is " + pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is " "older than oldest login, disallowing " "access to %s for user %s", path, service, ruser); @@ -516,7 +517,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) now = time(NULL); if (timestamp_good(then, now, interval) == PAM_SUCCESS) { close(fd); - syslog(LOG_NOTICE, MODULE ": timestamp file `%s' is " + pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' is " "only %ld seconds old, allowing access to %s " "for user %s", path, (long) (now - st.st_mtime), service, ruser); @@ -526,7 +527,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) return PAM_SUCCESS; } else { close(fd); - syslog(LOG_NOTICE, MODULE ": timestamp file `%s' has " + pam_syslog(pamh, LOG_NOTICE, "timestamp file `%s' has " "unacceptable age (%ld seconds), disallowing " "access to %s for user %s", path, (long) (now - st.st_mtime), @@ -580,10 +581,9 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) } else { if (errno != EEXIST) { if (debug) { - syslog(LOG_DEBUG, - MODULE ": error creating" - " directory `%s': %s", - subdir, strerror(errno)); + pam_syslog(pamh, LOG_DEBUG, + "error creating directory `%s': %m", + subdir); } return PAM_SESSION_ERR; } @@ -594,7 +594,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) /* Generate the message. */ text = malloc(strlen(path) + 1 + sizeof(now) + hmac_sha1_size()); if (text == NULL) { - syslog(LOG_ERR, MODULE ": unable to allocate memory: %m"); + pam_syslog(pamh, LOG_ERR, "unable to allocate memory: %m"); return PAM_SESSION_ERR; } p = text; @@ -612,7 +612,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) 0, 0, text, p - text); if (mac == NULL) { - syslog(LOG_ERR, MODULE ": failure generating MAC: %m"); + pam_syslog(pamh, LOG_ERR, "failure generating MAC: %m"); free(text); return PAM_SESSION_ERR; } @@ -623,7 +623,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) /* Open the file. */ fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); if (fd == -1) { - syslog(LOG_ERR, MODULE ": unable to open `%s': %m", path); + pam_syslog(pamh, LOG_ERR, "unable to open `%s': %m", path); free(text); return PAM_SESSION_ERR; } @@ -633,7 +633,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) /* Write the timestamp to the file. */ if (write(fd, text, p - text) != p - text) { - syslog(LOG_ERR, MODULE ": unable to write to `%s': %m", path); + pam_syslog(pamh, LOG_ERR, "unable to write to `%s': %m", path); close(fd); free(text); return PAM_SESSION_ERR; @@ -642,7 +642,7 @@ pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) /* Close the file and return successfully. */ close(fd); free(text); - syslog(LOG_DEBUG, MODULE ": updated timestamp file `%s'", path); + pam_syslog(pamh, LOG_DEBUG, "updated timestamp file `%s'", path); return PAM_SUCCESS; } @@ -751,7 +751,7 @@ main(int argc, char **argv) do { /* Sanity check the timestamp directory itself. */ if (retval == 0) { - if (check_dir_perms(TIMESTAMPDIR) != PAM_SUCCESS) { + if (check_dir_perms(NULL, TIMESTAMPDIR) != PAM_SUCCESS) { retval = 5; } } diff --git a/pam_timestamp/sha1.c b/pam_timestamp/sha1.c index b1a79a2..e6705eb 100644 --- a/pam_timestamp/sha1.c +++ b/pam_timestamp/sha1.c @@ -81,7 +81,7 @@ RL(u_int32_t n, u_int32_t s) } static u_int32_t -round(u_int32_t (*FUNC)(u_int32_t, u_int32_t, u_int32_t), +sha1_round(u_int32_t (*FUNC)(u_int32_t, u_int32_t, u_int32_t), u_int32_t a, u_int32_t b, u_int32_t c, u_int32_t d, u_int32_t e, u_int32_t i, u_int32_t n) { @@ -120,19 +120,19 @@ sha1_process(struct sha1_context *ctx, u_int32_t buffer[SHA1_BLOCK_SIZE / 4]) e = ctx->e; for (i = 0; i < 20; i++) { - temp = round(F, a, b, c, d, e, data[i], 0x5a827999); + temp = sha1_round(F, a, b, c, d, e, data[i], 0x5a827999); e = d; d = c; c = RL(b, 30); b = a; a = temp; } for (i = 20; i < 40; i++) { - temp = round(G, a, b, c, d, e, data[i], 0x6ed9eba1); + temp = sha1_round(G, a, b, c, d, e, data[i], 0x6ed9eba1); e = d; d = c; c = RL(b, 30); b = a; a = temp; } for (i = 40; i < 60; i++) { - temp = round(H, a, b, c, d, e, data[i], 0x8f1bbcdc); + temp = sha1_round(H, a, b, c, d, e, data[i], 0x8f1bbcdc); e = d; d = c; c = RL(b, 30); b = a; a = temp; } for (i = 60; i < 80; i++) { - temp = round(G, a, b, c, d, e, data[i], 0xca62c1d6); + temp = sha1_round(G, a, b, c, d, e, data[i], 0xca62c1d6); e = d; d = c; c = RL(b, 30); b = a; a = temp; } diff --git a/pam_xauth/README b/pam_xauth/README deleted file mode 100644 index dd65292..0000000 --- a/pam_xauth/README +++ /dev/null @@ -1,41 +0,0 @@ -pam_xauth: - Forward xauth cookies from user to user, normally used by su, sudo, or - userhelper. - - Primitive access control is provided by ~/.xauth/export in the invoking - user's home directory and ~/.xauth/import in the target user's home - directory. - - If a user has a ~/.xauth/import file, the user will only receive cookies - from users listed in the file. If there is no ~/.xauth/import file, - the user will accept cookies from any other user. - - If a user has a .xauth/export file, the user will only forward cookies - to users listed in the file. If there is no ~/.xauth/export file, and - the invoking user is not "root", the user will forward cookies to - any other user. If there is no ~/.xauth/export file, and the invoking - user is "root", the user will NOT forward cookies to other users. - - Both the import and export files support wildcards (such as "*"). Both - the import and export files can be empty, signifying that no users are - allowed. - -RECOGNIZED ARGUMENTS: - debug write debugging messages to syslog - xauthpath= the path to the xauth program, by default - /usr/X11R6/bin/xauth - systemuser= highest user id assigned to system users, defaults - to 499 (pam_xauth will refuse to forward creds to - target users with id equal to or below this number, - except for root and possibly another specified user) - targetuser= a target user id which is excepted from the systemuser - checks - - -MODULE SERVICES PROVIDED: - session open session copies xauth cookie to new user - close session deletes copied xauth cookie - -AUTHOR: - Nalin Dahyabhai , based on original version by - Michael K. Johnson diff --git a/pam_xauth/pam_xauth.8 b/pam_xauth/pam_xauth.8 deleted file mode 100644 index 9acb724..0000000 --- a/pam_xauth/pam_xauth.8 +++ /dev/null @@ -1,82 +0,0 @@ -.\" Copyright 2001,2003 Red Hat, Inc. -.\" Written by Nalin Dahyabhai , based on the original -.\" version by Michael K. Johnson -.TH pam_xauth 8 2003/7/24 "Red Hat Linux" "System Administrator's Manual" -.SH NAME -pam_xauth \- forward xauth keys between users -.SH SYNOPSIS -.B session optional /lib/security/pam_xauth.so \fIarguments\fP -.SH DESCRIPTION -pam_xauth.so is designed to forward xauth keys (sometimes referred -to as "cookies") between users. - -Without pam_xauth, when xauth is enabled and a user uses the \fBsu\fP command -to assume another user's priviledges, that user is no longer able to access -the original user's X display because the new user does not have the key -needed to access the display. pam_xauth solves the problem by forwarding the -key from the user running su (the source user) to the user whose -identity the source user is assuming (the target user) when the session -is created, and destroying the key when the session is torn down. - -This means, for example, that when you run \fBsu\fP from an xterm sesssion, -you will be able to run X programs without explicitly dealing with the -xauth command or ~/.Xauthority files. - -pam_xauth will only forward keys if xauth can list a key connected -to the $DISPLAY environment variable. - -Primitive access control is provided by \fB~/.xauth/export\fP in the invoking -user's home directory and \fB~/.xauth/import\fP in the target user's home -directory. - -If a user has a \fB~/.xauth/import\fP file, the user will only receive cookies -from users listed in the file. If there is no \fB~/.xauth/import\fP file, -the user will accept cookies from any other user. - -If a user has a \fB.xauth/export\fP file, the user will only forward cookies -to users listed in the file. If there is no \fB~/.xauth/export\fP file, and -the invoking user is not \fBroot\fP, the user will forward cookies to -any other user. If there is no \fB~/.xauth/export\fP file, and the invoking -user is \fBroot\fP, the user will \fInot\fP forward cookies to other users. - -Both the import and export files support wildcards (such as \fI*\fP). Both -the import and export files can be empty, signifying that no users are allowed. - -.SH ARGUMENTS -.IP debug -Turns on debugging messages sent to syslog. -.IP xauthpath=\fI/usr/X11R6/bin/xauth\fP -Specify the path the xauth program (the default is /usr/X11R6/bin/xauth). -.IP systemuser=\fInumber\fP -Specify the highest UID which will be assumed to belong to a "system" user. -pam_xauth will refuse to forward credentials to users with UID less than or -equal to this number, except for root and the "targetuser", if specified. -.IP targetuser=\fInumber\fP -Specify a single target UID which is exempt from the systemuser check. -.SH "IMPLEMENTATION DETAILS" -pam_xauth will work \fIonly\fP if it is used from a setuid application -in which the getuid() call returns the id of the user running the -application, and for which PAM can supply the name of the account that -the user is attempting to assume. The typical application of this -type is \fBsu\fP. The application must call both pam_open_session() and -pam_close_session() with the ruid set to the uid of the calling user -and the euid set to root, and must have provided as the PAM_USER item -the name of the target user. - -pam_xauth calls \fBxauth\fP as the source user to extract the key for -$DISPLAY, then calls xauth as the target user to merge the key -into the a temporary database and later remove the database. - -pam_xauth cannot be told not to remove the keys when the session -is closed. -.SH "SEE ALSO" -\fI/usr/share/doc/pam*/html/index.html\fP -.SH FILES -\fI~/.xauth/import\fP -\fI~/.xauth/export\fP -.SH BUGS -Let's hope not, but if you find any, please report them via the "Bug Track" -link at http://bugzilla.redhat.com/bugzilla/ -.SH AUTHOR -Nalin Dahyabhai , based on original version by -Michael K. Johnson diff --git a/pam_xauth/pam_xauth.c b/pam_xauth/pam_xauth.c deleted file mode 100644 index ffde45b..0000000 --- a/pam_xauth/pam_xauth.c +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Copyright 2001-2003 Red Hat, Inc. - * - * 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. - */ - -#ident "$Id$" - -#include "../../_pam_aconf.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define DATANAME "pam_xauth_cookie_file" -#define XAUTHBIN "/usr/X11R6/bin/xauth" -#define XAUTHENV "XAUTHORITY" -#define HOMEENV "HOME" -#define XAUTHDEF ".Xauthority" -#define XAUTHTMP ".xauthXXXXXX" - -/* Run a given command (with a NULL-terminated argument list), feeding it the - * given input on stdin, and storing any output it generates. */ -static int -run_coprocess(const char *input, char **output, - uid_t uid, gid_t gid, const char *command, ...) -{ - int ipipe[2], opipe[2], i; - char buf[LINE_MAX]; - pid_t child; - char *buffer = NULL; - size_t buffer_size = 0; - va_list ap; - - *output = NULL; - - /* Create stdio pipery. */ - if (pipe(ipipe) == -1) { - return -1; - } - if (pipe(opipe) == -1) { - close(ipipe[0]); - close(ipipe[1]); - return -1; - } - - /* Fork off a child. */ - child = fork(); - if (child == -1) { - close(ipipe[0]); - close(ipipe[1]); - close(opipe[0]); - close(opipe[1]); - return -1; - } - - if (child == 0) { - /* We're the child. */ - char *args[10]; - const char *tmp; - /* Drop privileges. */ - setgid(gid); - setgroups(0, NULL); - setuid(uid); - /* Initialize the argument list. */ - memset(args, 0, sizeof(args)); - /* Set the pipe descriptors up as stdin and stdout, and close - * everything else, including the original values for the - * descriptors. */ - dup2(ipipe[0], STDIN_FILENO); - dup2(opipe[1], STDOUT_FILENO); - for (i = 0; i < sysconf(_SC_OPEN_MAX); i++) { - if ((i != STDIN_FILENO) && (i != STDOUT_FILENO)) { - close(i); - } - } - /* Convert the varargs list into a regular array of strings. */ - va_start(ap, command); - args[0] = strdup(command); - for (i = 1; i < ((sizeof(args) / sizeof(args[0])) - 1); i++) { - tmp = va_arg(ap, const char*); - if (tmp == NULL) { - break; - } - args[i] = strdup(tmp); - } - /* Run the command. */ - execvp(command, args); - /* Never reached. */ - exit(1); - } - - /* We're the parent, so close the other ends of the pipes. */ - close(ipipe[0]); - close(opipe[1]); - /* Send input to the process (if we have any), then send an EOF. */ - if (input) { - (void)_pammodutil_write(ipipe[1], input, strlen(input)); - } - close(ipipe[1]); - - /* Read data output until we run out of stuff to read. */ - i = _pammodutil_read(opipe[0], buf, sizeof(buf)); - while ((i != 0) && (i != -1)) { - char *tmp; - /* Resize the buffer to hold the data. */ - tmp = realloc(buffer, buffer_size + i + 1); - if (tmp == NULL) { - /* Uh-oh, bail. */ - if (buffer != NULL) { - free(buffer); - } - close(opipe[0]); - waitpid(child, NULL, 0); - return -1; - } - /* Save the new buffer location, copy the newly-read data into - * the buffer, and make sure the result will be - * nul-terminated. */ - buffer = tmp; - memcpy(buffer + buffer_size, buf, i); - buffer[buffer_size + i] = '\0'; - buffer_size += i; - /* Try to read again. */ - i = _pammodutil_read(opipe[0], buf, sizeof(buf)); - } - /* No more data. Clean up and return data. */ - close(opipe[0]); - *output = buffer; - waitpid(child, NULL, 0); - return 0; -} - -/* Free a data item. */ -static void -cleanup(pam_handle_t *pamh, void *data, int err) -{ - free(data); -} - -/* Check if we want to allow export to the other user, or import from the - * other user. */ -static int -check_acl(pam_handle_t *pamh, - const char *sense, const char *this_user, const char *other_user, - int noent_code, int debug) -{ - char path[PATH_MAX]; - struct passwd *pwd; - FILE *fp; - int i; - uid_t euid; - /* Check this user's file. */ - pwd = _pammodutil_getpwnam(pamh, this_user); - if (pwd == NULL) { - syslog(LOG_ERR, "pam_xauth: error determining " - "home directory for '%s'", this_user); - return PAM_SESSION_ERR; - } - /* Figure out what that file is really named. */ - i = snprintf(path, sizeof(path), "%s/.xauth/%s", pwd->pw_dir, sense); - if ((i >= sizeof(path)) || (i < 0)) { - syslog(LOG_ERR, "pam_xauth: name of user's home directory " - "is too long"); - return PAM_SESSION_ERR; - } - euid = geteuid(); - setfsuid(pwd->pw_uid); - fp = fopen(path, "r"); - setfsuid(euid); - if (fp != NULL) { - char buf[LINE_MAX], *tmp; - /* Scan the file for a list of specs of users to "trust". */ - while (fgets(buf, sizeof(buf), fp) != NULL) { - tmp = memchr(buf, '\r', sizeof(buf)); - if (tmp != NULL) { - *tmp = '\0'; - } - tmp = memchr(buf, '\n', sizeof(buf)); - if (tmp != NULL) { - *tmp = '\0'; - } - if (fnmatch(buf, other_user, 0) == 0) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: %s %s " - "allowed by %s", - other_user, sense, path); - } - fclose(fp); - return PAM_SUCCESS; - } - } - /* If there's no match in the file, we fail. */ - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: %s not listed in %s", - other_user, path); - } - fclose(fp); - return PAM_PERM_DENIED; - } else { - /* Default to okay if the file doesn't exist. */ - switch (errno) { - case ENOENT: - if (noent_code == PAM_SUCCESS) { - if (debug) { - syslog(LOG_DEBUG, "%s does not exist, " - "ignoring", path); - } - } else { - if (debug) { - syslog(LOG_DEBUG, "%s does not exist, " - "failing", path); - } - } - return noent_code; - default: - if (debug) { - syslog(LOG_ERR, "%s opening %s", - strerror(errno), path); - } - return PAM_PERM_DENIED; - } - } -} - -int -pam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - char xauthpath[] = XAUTHBIN; - char *cookiefile = NULL, *xauthority = NULL, - *cookie = NULL, *display = NULL, *tmp = NULL; - const char *user, *xauth = xauthpath; - struct passwd *tpwd, *rpwd; - int fd, i, debug = 0; - int retval = PAM_SUCCESS; - uid_t systemuser = 499, targetuser = 0, euid; - - /* Parse arguments. We don't understand many, so no sense in breaking - * this into a separate function. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - continue; - } - if (strncmp(argv[i], "xauthpath=", 10) == 0) { - xauth = argv[i] + 10; - continue; - } - if (strncmp(argv[i], "targetuser=", 11) == 0) { - long l = strtol(argv[i] + 11, &tmp, 10); - if ((strlen(argv[i] + 11) > 0) && (*tmp == '\0')) { - targetuser = l; - } else { - syslog(LOG_WARNING, "pam_xauth: invalid value " - "for targetuser (`%s')", argv[i] + 11); - } - continue; - } - if (strncmp(argv[i], "systemuser=", 11) == 0) { - long l = strtol(argv[i] + 11, &tmp, 10); - if ((strlen(argv[i] + 11) > 0) && (*tmp == '\0')) { - systemuser = l; - } else { - syslog(LOG_WARNING, "pam_xauth: invalid value " - "for systemuser (`%s')", argv[i] + 11); - } - continue; - } - syslog(LOG_WARNING, "pam_xauth: unrecognized option `%s'", - argv[i]); - } - - /* If DISPLAY isn't set, we don't really care, now do we? */ - if ((display = getenv("DISPLAY")) == NULL) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: user has no DISPLAY," - " doing nothing"); - } - return PAM_SUCCESS; - } - - /* Read the target user's name. */ - if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_xauth: error determining target " - "user's name"); - retval = PAM_SESSION_ERR; - goto cleanup; - } - rpwd = _pammodutil_getpwuid(pamh, getuid()); - if (rpwd == NULL) { - syslog(LOG_ERR, "pam_xauth: error determining invoking " - "user's name"); - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Get the target user's UID and primary GID, which we'll need to set - * on the xauthority file we create later on. */ - tpwd = _pammodutil_getpwnam(pamh, user); - if (tpwd == NULL) { - syslog(LOG_ERR, "pam_xauth: error determining target " - "user's UID"); - retval = PAM_SESSION_ERR; - goto cleanup; - } - - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: requesting user %lu/%lu, " - "target user %lu/%lu", - (unsigned long) rpwd->pw_uid, - (unsigned long) rpwd->pw_gid, - (unsigned long) tpwd->pw_uid, - (unsigned long) tpwd->pw_gid); - } - - /* If the UID is a system account (and not the superuser), forget - * about forwarding keys. */ - if ((tpwd->pw_uid != 0) && - (tpwd->pw_uid != targetuser) && - (tpwd->pw_uid <= systemuser)) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: not forwarding cookies " - "to user ID %ld", (long) tpwd->pw_uid); - } - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Check that both users are amenable to this. By default, this - * boils down to this policy: - * export(ruser=root): only if is listed in .xauth/export - * export(ruser=*) if is listed in .xauth/export, or - * if .xauth/export does not exist - * import(user=*): if is listed in .xauth/import, or - * if .xauth/import does not exist */ - i = (getuid() != 0 || tpwd->pw_uid == 0) ? PAM_SUCCESS : PAM_PERM_DENIED; - i = check_acl(pamh, "export", rpwd->pw_name, user, i, debug); - if (i != PAM_SUCCESS) { - retval = PAM_SESSION_ERR; - goto cleanup; - } - i = PAM_SUCCESS; - i = check_acl(pamh, "import", user, rpwd->pw_name, i, debug); - if (i != PAM_SUCCESS) { - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Figure out where the source user's .Xauthority file is. */ - if (getenv(XAUTHENV) != NULL) { - cookiefile = strdup(getenv(XAUTHENV)); - } else { - cookiefile = malloc(strlen(rpwd->pw_dir) + 1 + - strlen(XAUTHDEF) + 1); - if (cookiefile == NULL) { - retval = PAM_SESSION_ERR; - goto cleanup; - } - strcpy(cookiefile, rpwd->pw_dir); - strcat(cookiefile, "/"); - strcat(cookiefile, XAUTHDEF); - } - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: reading keys from `%s'", - cookiefile); - } - - /* Read the user's .Xauthority file. Because the current UID is - * the original user's UID, this will only fail if something has - * gone wrong, or we have no cookies. */ - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: running \"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nlist", - display, - (unsigned long) getuid(), - (unsigned long) getgid()); - } - if (run_coprocess(NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, "nlist", display, - NULL) == 0) { - /* Check that we got a cookie. If not, we get creative. */ - if (((cookie == NULL) || (strlen(cookie) == 0)) && - ((strncmp(display, "localhost:", 10) == 0) || - (strncmp(display, "localhost/unix:", 15) == 0))) { - char *t, *screen; - size_t tlen, slen; - /* Free the useless cookie string. */ - if (cookie != NULL) { - free(cookie); - cookie = NULL; - } - /* Allocate enough space to hold an adjusted name. */ - tlen = strlen(display) + LINE_MAX + 1; - t = malloc(tlen); - if (t != NULL) { - memset(t, 0, tlen); - if (gethostname(t, tlen - 1) != -1) { - /* Append the protocol and then the - * screen number. */ - if (strlen(t) < tlen - 6) { - strcat(t, "/unix:"); - } - screen = strchr(display, ':'); - if (screen != NULL) { - screen++; - slen = strlen(screen); - if (strlen(t) + slen < tlen) { - strcat(t, screen); - } - } - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: " - "no key for `%s', trying" - " `%s'", display, t); - } - /* Read the cookie for this display. */ - if (debug) { - syslog(LOG_DEBUG, - "pam_xauth: running " - "\"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nlist", - t, - (unsigned long) getuid(), - (unsigned long) getgid()); - } - run_coprocess(NULL, &cookie, - getuid(), getgid(), - xauth, "-f", cookiefile, - "nlist", t, NULL); - } - free(t); - t = NULL; - } - } - - /* Check that we got a cookie, this time for real. */ - if ((cookie == NULL) || (strlen(cookie) == 0)) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: no key"); - } - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Generate the environment variable - * "XAUTHORITY=/filename". */ - xauthority = malloc(strlen(XAUTHENV) + 1 + - strlen(tpwd->pw_dir) + 1 + - strlen(XAUTHTMP) + 1); - if (xauthority == NULL) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: no free memory"); - } - retval = PAM_SESSION_ERR; - goto cleanup; - } - strcpy(xauthority, XAUTHENV); - strcat(xauthority, "="); - strcat(xauthority, tpwd->pw_dir); - strcat(xauthority, "/"); - strcat(xauthority, XAUTHTMP); - - /* Generate a new file to hold the data. */ - euid = geteuid(); - setfsuid(tpwd->pw_uid); - fd = mkstemp(xauthority + strlen(XAUTHENV) + 1); - setfsuid(euid); - if (fd == -1) { - syslog(LOG_ERR, "pam_xauth: error creating " - "temporary file `%s': %s", - xauthority + strlen(XAUTHENV) + 1, - strerror(errno)); - retval = PAM_SESSION_ERR; - goto cleanup; - } - /* Set permissions on the new file and dispose of the - * descriptor. */ - fchown(fd, tpwd->pw_uid, tpwd->pw_gid); - close(fd); - - /* Get a copy of the filename to save as a data item for - * removal at session-close time. */ - free(cookiefile); - cookiefile = strdup(xauthority + strlen(XAUTHENV) + 1); - - /* Save the filename. */ - if (pam_set_data(pamh, DATANAME, cookiefile, cleanup) != PAM_SUCCESS) { - syslog(LOG_ERR, "pam_xauth: error saving name of " - "temporary file `%s'", cookiefile); - unlink(cookiefile); - retval = PAM_SESSION_ERR; - goto cleanup; - } - - /* Set the new variable in the environment. */ - if (pam_putenv (pamh, xauthority) != PAM_SUCCESS) - syslog (LOG_DEBUG, "pam_xauth: can't set environment variable '%s'", - xauthority); - putenv (xauthority); /* The environment owns this string now. */ - - /* set $DISPLAY in pam handle to make su - work */ - { - char *d = (char *) malloc (strlen ("DISPLAY=") + - strlen (display) + 1); - if (d == NULL) - { - syslog (LOG_DEBUG, "pam_xauth: memory exhausted"); - cookiefile = NULL; - retval = PAM_SESSION_ERR; - goto cleanup; - } - strcpy (d, "DISPLAY="); - strcat (d, display); - - if (pam_putenv (pamh, d) != PAM_SUCCESS) - syslog (LOG_DEBUG, - "pam_xauth: can't set environment variable '%s'", - d); - free (d); - } - - /* Merge the cookie we read before into the new file. */ - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: writing key `%s' to " - "temporary file `%s'", cookie, cookiefile); - } - if (debug) { - syslog(LOG_DEBUG, - "pam_xauth: running \"%s %s %s %s %s\" as " - "%lu/%lu", - xauth, - "-f", - cookiefile, - "nmerge", - "-", - (unsigned long) tpwd->pw_uid, - (unsigned long) tpwd->pw_gid); - } - run_coprocess(cookie, &tmp, - tpwd->pw_uid, tpwd->pw_gid, - xauth, "-f", cookiefile, "nmerge", "-", NULL); - - /* We don't need to keep a copy of these around any more. */ - cookiefile = NULL; - free(tmp); - } -cleanup: - /* Unset any old XAUTHORITY variable in the environment. */ - if (retval != PAM_SUCCESS && getenv (XAUTHENV)) - unsetenv (XAUTHENV); - free(cookiefile); - free(cookie); - free(xauthority); - return retval; -} - -int -pam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv) -{ - void *cookiefile; - int i, debug = 0; - - /* Parse arguments. We don't understand many, so no sense in breaking - * this into a separate function. */ - for (i = 0; i < argc; i++) { - if (strcmp(argv[i], "debug") == 0) { - debug = 1; - continue; - } - if (strncmp(argv[i], "xauthpath=", 10) == 0) { - continue; - } - if (strncmp(argv[i], "systemuser=", 11) == 0) { - continue; - } - if (strncmp(argv[i], "targetuser=", 11) == 0) { - continue; - } - syslog(LOG_WARNING, "pam_xauth: unrecognized option `%s'", - argv[i]); - } - - /* Try to retrieve the name of a file we created when the session was - * opened. */ - if (pam_get_data(pamh, DATANAME, (const void**) &cookiefile) == PAM_SUCCESS) { - /* We'll only try to remove the file once. */ - if (strlen((char*)cookiefile) > 0) { - if (debug) { - syslog(LOG_DEBUG, "pam_xauth: removing `%s'", - (char*)cookiefile); - } - unlink((char*)cookiefile); - *((char*)cookiefile) = '\0'; - } - } - return PAM_SUCCESS; -}