diff options
author | Tomas Mraz <tm@t8m.info> | 2009-02-27 14:29:39 +0000 |
---|---|---|
committer | Tomas Mraz <tm@t8m.info> | 2009-02-27 14:29:39 +0000 |
commit | 42f4743cc3ca046833afcaeec01f9793d74bbfb4 (patch) | |
tree | b969c921b0a5a924b09cf4d34ac74b01b309425c /modules | |
parent | 5891c5508e3b9ba699a6a6ba3dae9221a45528e5 (diff) | |
download | pam-42f4743cc3ca046833afcaeec01f9793d74bbfb4.tar.gz pam-42f4743cc3ca046833afcaeec01f9793d74bbfb4.tar.bz2 pam-42f4743cc3ca046833afcaeec01f9793d74bbfb4.zip |
Relevant BUGIDs:
Purpose of commit: new feature
Commit summary:
---------------
2009-02-27 Tomas Mraz <t8m@centrum.cz>
* modules/pam_mkhomedir/pam_mkhomedir.c(create_homedir): Replace
signal() with sigaction().
* modules/pam_namespace/pam_namespace.c(inst_init, cleanup_tmpdirs):
Likewise.
* modules/pam_unix/pam_unix_acct.c(_unix_run_verify_binary): Likewise.
* modules/pam_unix/pam_unix_passwd.c(_unix_run_update_binary):
Likewise.
* modules/pam_unix/passverify.c(su_sighandler): Likewise.
* modules/pam_unix/support.c(_unix_run_helper_binary): Likewise.
* modules/pam_tally2/Makefile.am: Link the pam_tally2 app to libpam
for auxiliary functions.
* modules/pam_tally2/pam_tally2.8.xml: Drop non-existing no_reset
option. Document new serialize option.
* modules/pam_tally2/pam_tally2.c: Add support for the new serialize
option.
(_cleanup, tally_set_data, tally_get_data): Add tally file handle to
tally PAM data. Needed for fcntl() locking.
(get_tally): Use low level file access instead of stdio buffered FILE.
If serialize option is used lock the tally file access.
(set_tally, tally_bump, tally_reset): Use low level file access instead
of stdio buffered FILE. Close the file handle only when it is not owned
by PAM data.
(pam_sm_authenticate, pam_sm_setcred, pam_sm_acct_mgmt): Pass the tally
file handle to tally_set_data(). Get it from tally_get_data().
(main): Use low level file access instead of stdio buffered FILE.
Diffstat (limited to 'modules')
-rw-r--r-- | modules/pam_mkhomedir/pam_mkhomedir.c | 12 | ||||
-rw-r--r-- | modules/pam_namespace/pam_namespace.c | 24 | ||||
-rw-r--r-- | modules/pam_tally2/Makefile.am | 2 | ||||
-rw-r--r-- | modules/pam_tally2/pam_tally2.8.xml | 32 | ||||
-rw-r--r-- | modules/pam_tally2/pam_tally2.c | 216 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_acct.c | 12 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_passwd.c | 10 | ||||
-rw-r--r-- | modules/pam_unix/passverify.c | 8 | ||||
-rw-r--r-- | modules/pam_unix/support.c | 10 |
9 files changed, 210 insertions, 116 deletions
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index a0c389c5..1beb2d9f 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -104,7 +104,7 @@ create_homedir (pam_handle_t *pamh, int ctrl, const struct passwd *pwd) { int retval, child; - void (*sighandler)(int) = NULL; + struct sigaction newsa, oldsa; /* Mention what is happening, if the notification fails that is OK */ if (!(ctrl & MKHOMEDIR_QUIET)) @@ -118,8 +118,10 @@ create_homedir (pam_handle_t *pamh, int ctrl, * the application to receive a signal it is not expecting - which * may kill the application or worse. */ - sighandler = signal(SIGCHLD, SIG_DFL); - + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &newsa, &oldsa); + if (ctrl & MKHOMEDIR_DEBUG) { pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper."); } @@ -166,9 +168,7 @@ create_homedir (pam_handle_t *pamh, int ctrl, retval = PAM_SYSTEM_ERR; } - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ - } + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ if (ctrl & MKHOMEDIR_DEBUG) { pam_syslog(pamh, LOG_DEBUG, "mkhomedir_helper returned %d", retval); diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c index 89bc3686..7d668d9e 100644 --- a/modules/pam_namespace/pam_namespace.c +++ b/modules/pam_namespace/pam_namespace.c @@ -1157,15 +1157,15 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath, struct instance_data *idata, int newdir) { pid_t rc, pid; - sighandler_t osighand = NULL; + struct sigaction newsa, oldsa; int status; const char *init_script = NAMESPACE_INIT_SCRIPT; - osighand = signal(SIGCHLD, SIG_DFL); - if (osighand == SIG_ERR) { + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value"); - rc = PAM_SESSION_ERR; - goto out; + return PAM_SESSION_ERR; } if ((polyptr->flags & POLYDIR_ISCRIPT) && polyptr->init_script) @@ -1214,7 +1214,7 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath, } rc = PAM_SUCCESS; out: - (void) signal(SIGCHLD, osighand); + (void) sigaction(SIGCHLD, &oldsa, NULL); return rc; } @@ -1594,14 +1594,14 @@ static int cleanup_tmpdirs(struct instance_data *idata) { struct polydir_s *pptr; pid_t rc, pid; - sighandler_t osighand = NULL; + struct sigaction newsa, oldsa; int status; - osighand = signal(SIGCHLD, SIG_DFL); - if (osighand == SIG_ERR) { + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value"); - rc = PAM_SESSION_ERR; - goto out; + return PAM_SESSION_ERR; } for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) { @@ -1639,7 +1639,7 @@ static int cleanup_tmpdirs(struct instance_data *idata) rc = PAM_SUCCESS; out: - signal(SIGCHLD, osighand); + sigaction(SIGCHLD, &oldsa, NULL); return rc; } diff --git a/modules/pam_tally2/Makefile.am b/modules/pam_tally2/Makefile.am index 6f843e1f..06cdf554 100644 --- a/modules/pam_tally2/Makefile.am +++ b/modules/pam_tally2/Makefile.am @@ -25,7 +25,7 @@ if HAVE_VERSIONING pam_tally2_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map endif -pam_tally2_LDADD = $(LIBAUDIT) +pam_tally2_LDADD = -L$(top_builddir)/libpam -lpam $(LIBAUDIT) securelib_LTLIBRARIES = pam_tally2.la sbin_PROGRAMS = pam_tally2 diff --git a/modules/pam_tally2/pam_tally2.8.xml b/modules/pam_tally2/pam_tally2.8.xml index a7a3fc47..255fcea4 100644 --- a/modules/pam_tally2/pam_tally2.8.xml +++ b/modules/pam_tally2/pam_tally2.8.xml @@ -43,6 +43,9 @@ root_unlock_time=<replaceable>n</replaceable> </arg> <arg choice="opt"> + serialize + </arg> + <arg choice="opt"> audit </arg> <arg choice="opt"> @@ -246,16 +249,6 @@ </varlistentry> <varlistentry> <term> - <option>no_reset</option> - </term> - <listitem> - <para> - Don't reset count on successful entry, only decrement. - </para> - </listitem> - </varlistentry> - <varlistentry> - <term> <option>even_deny_root</option> </term> <listitem> @@ -278,6 +271,23 @@ </para> </listitem> </varlistentry> + <varlistentry> + <term> + <option>serialize</option> + </term> + <listitem> + <para> + Serialize access to the tally file using locks. This option might + be used only for non-multithreaded services because it depends on + the fcntl locking of the tally file. Also it is a good idea to use + this option only in such configurations where the time between auth + phase and account or setcred phase is not dependent on the + authenticating client. Otherwise the authenticating client will be + able to prevent simultaneous authentications by the same user by + simply artificially prolonging the time the file record lock is held. + </para> + </listitem> + </varlistentry> </variablelist> </listitem> </varlistentry> @@ -431,7 +441,7 @@ session optional pam_mail.so standard <refsect1 id='pam_tally2-author'> <title>AUTHOR</title> <para> - pam_tally was written by Tim Baverstock and Tomas Mraz. + pam_tally2 was written by Tim Baverstock and Tomas Mraz. </para> </refsect1> diff --git a/modules/pam_tally2/pam_tally2.c b/modules/pam_tally2/pam_tally2.c index faa6942e..3490aa15 100644 --- a/modules/pam_tally2/pam_tally2.c +++ b/modules/pam_tally2/pam_tally2.c @@ -63,6 +63,9 @@ #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> +#include <fcntl.h> +#include <unistd.h> +#include <signal.h> #include "tallylog.h" #ifndef TRUE @@ -87,9 +90,9 @@ /* #define PAM_SM_SESSION */ /* #define PAM_SM_PASSWORD */ -#include <security/pam_modutil.h> #include <security/pam_ext.h> #endif +#include <security/pam_modutil.h> #include <security/pam_modules.h> /*---------------------------------------------------------------------*/ @@ -120,7 +123,9 @@ struct tally_options { #define OPT_QUIET 040 #define OPT_AUDIT 0100 #define OPT_NOLOGNOTICE 0400 +#define OPT_SERIALIZE 01000 +#define MAX_LOCK_WAITING_TIME 10 /*---------------------------------------------------------------------*/ @@ -188,6 +193,9 @@ tally_parse_args(pam_handle_t *pamh, struct tally_options *opts, else if ( ! strcmp( *argv, "magic_root" ) ) { opts->ctrl |= OPT_MAGIC_ROOT; } + else if ( ! strcmp( *argv, "serialize" ) ) { + opts->ctrl |= OPT_SERIALIZE; + } else if ( ! strcmp( *argv, "even_deny_root_account" ) || ! strcmp( *argv, "even_deny_root" ) ) { log_phase_no_auth(pamh, phase, *argv); @@ -291,34 +299,44 @@ pam_get_uid(pam_handle_t *pamh, uid_t *uid, const char **userp, struct tally_opt #ifndef MAIN +struct tally_data { + time_t time; + int tfile; +}; + static void -_cleanup(pam_handle_t *pamh UNUSED, void *data, int error_status UNUSED) +_cleanup(pam_handle_t *pamh UNUSED, void *void_data, int error_status UNUSED) { + struct tally_data *data = void_data; + if (data->tfile != -1) + close(data->tfile); free(data); } - static void -tally_set_data( pam_handle_t *pamh, time_t oldtime ) +tally_set_data( pam_handle_t *pamh, time_t oldtime, int tfile ) { - time_t *data; + struct tally_data *data; - if ( (data=malloc(sizeof(time_t))) != NULL ) { - *data = oldtime; + if ( (data=malloc(sizeof(*data))) != NULL ) { + data->time = oldtime; + data->tfile = tfile; pam_set_data(pamh, MODULE_NAME, (void *)data, _cleanup); } } static int -tally_get_data( pam_handle_t *pamh, time_t *oldtime ) +tally_get_data( pam_handle_t *pamh, time_t *oldtime, int *tfile ) { int rv; - const void *data; - - rv = pam_get_data(pamh, MODULE_NAME, &data); - if ( rv == PAM_SUCCESS && data != NULL && oldtime != NULL ) { - *oldtime = *(const time_t *)data; - pam_set_data(pamh, MODULE_NAME, NULL, NULL); + const void *void_data; + const struct tally_data *data; + + rv = pam_get_data(pamh, MODULE_NAME, &void_data); + if ( rv == PAM_SUCCESS && void_data != NULL && oldtime != NULL ) { + data = void_data; + *oldtime = data->time; + *tfile = data->tfile; } else { rv = -1; @@ -334,36 +352,44 @@ tally_get_data( pam_handle_t *pamh, time_t *oldtime ) /* If on entry tallyfile doesn't exist, creation is attempted. */ +static void +alarm_handler(int sig UNUSED) +{ /* we just need to ignore it */ +} + static int get_tally(pam_handle_t *pamh, uid_t uid, const char *filename, - FILE **tfile, struct tallylog *tally) + int *tfile, struct tallylog *tally, unsigned int ctrl) { struct stat fileinfo; int lstat_ret; + void *void_tally = tally; + int preopened = 0; + + if (*tfile != -1) { + preopened = 1; + goto skip_open; + } lstat_ret = lstat(filename, &fileinfo); if (lstat_ret) { - int save_errno; - int oldmask = umask(077); - *tfile=fopen(filename, "a"); - save_errno = errno; + *tfile=open(filename, O_APPEND|O_CREAT, 0700); /* Create file, or append-open in pathological case. */ - umask(oldmask); - if ( !*tfile ) { + if (*tfile == -1) { #ifndef MAIN - if (save_errno == EACCES) { + if (errno == EACCES) { return PAM_IGNORE; /* called with insufficient access rights */ } #endif - errno = save_errno; pam_syslog(pamh, LOG_ALERT, "Couldn't create %s: %m", filename); return PAM_AUTH_ERR; } - lstat_ret = fstat(fileno(*tfile),&fileinfo); - fclose(*tfile); - *tfile = NULL; + lstat_ret = fstat(*tfile, &fileinfo); + close(*tfile); } + *tfile = -1; + if ( lstat_ret ) { pam_syslog(pamh, LOG_ALERT, "Couldn't stat %s", filename); return PAM_AUTH_ERR; @@ -378,7 +404,7 @@ get_tally(pam_handle_t *pamh, uid_t uid, const char *filename, return PAM_AUTH_ERR; } - if (!(*tfile = fopen(filename, "r+"))) { + if ((*tfile = open(filename, O_RDWR)) == -1) { #ifndef MAIN if (errno == EACCES) /* called with insufficient access rights */ return PAM_IGNORE; @@ -388,16 +414,46 @@ get_tally(pam_handle_t *pamh, uid_t uid, const char *filename, return PAM_AUTH_ERR; } - if (fseeko(*tfile, (off_t)uid*(off_t)sizeof(*tally), SEEK_SET)) { - pam_syslog(pamh, LOG_ALERT, "fseek failed for %s: %m", filename); - fclose(*tfile); - *tfile = NULL; +skip_open: + if (lseek(*tfile, (off_t)uid*(off_t)sizeof(*tally), SEEK_SET) == (off_t)-1) { + pam_syslog(pamh, LOG_ALERT, "lseek failed for %s: %m", filename); + if (!preopened) { + close(*tfile); + *tfile = -1; + } return PAM_AUTH_ERR; } + if (!preopened && (ctrl & OPT_SERIALIZE)) { + /* this code is not thread safe as it uses fcntl locks and alarm() + so never use serialize with multithreaded services */ + struct sigaction newsa, oldsa; + unsigned int oldalarm; + int rv; + + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = alarm_handler; + sigaction(SIGALRM, &newsa, &oldsa); + oldalarm = alarm(MAX_LOCK_WAITING_TIME); + + rv = lockf(*tfile, F_LOCK, sizeof(*tally)); + /* lock failure is not fatal, we attempt to read the tally anyway */ + + /* reinstate the eventual old alarm handler */ + if (rv == -1 && errno == EINTR) { + if (oldalarm > MAX_LOCK_WAITING_TIME) { + oldalarm -= MAX_LOCK_WAITING_TIME; + } else if (oldalarm > 0) { + oldalarm = 1; + } + } + sigaction(SIGALRM, &oldsa, NULL); + alarm(oldalarm); + } + if (fileinfo.st_size < (off_t)(uid+1)*(off_t)sizeof(*tally)) { memset(tally, 0, sizeof(*tally)); - } else if (fread(tally, sizeof(*tally), 1, *tfile) == 0) { + } else if (pam_modutil_read(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) { memset(tally, 0, sizeof(*tally)); /* Shouldn't happen */ } @@ -409,29 +465,28 @@ get_tally(pam_handle_t *pamh, uid_t uid, const char *filename, /*---------------------------------------------------------------------*/ -/* --- Support function: update and close tallyfile with tally!=TALLY_HI --- */ +/* --- Support function: update tallyfile with tally!=TALLY_HI --- */ static int set_tally(pam_handle_t *pamh, uid_t uid, - const char *filename, FILE **tfile, struct tallylog *tally) + const char *filename, int *tfile, struct tallylog *tally) { + void *void_tally = tally; if (tally->fail_cnt != TALLY_HI) { - if (fseeko(*tfile, (off_t)uid * sizeof(*tally), SEEK_SET)) { - pam_syslog(pamh, LOG_ALERT, "fseek failed for %s: %m", filename); + if (lseek(*tfile, (off_t)uid * sizeof(*tally), SEEK_SET) == (off_t)-1) { + pam_syslog(pamh, LOG_ALERT, "lseek failed for %s: %m", filename); return PAM_AUTH_ERR; } - if (fwrite(tally, sizeof(*tally), 1, *tfile) == 0) { - pam_syslog(pamh, LOG_ALERT, "update (fwrite) failed for %s: %m", filename); + if (pam_modutil_write(*tfile, void_tally, sizeof(*tally)) != sizeof(*tally)) { + pam_syslog(pamh, LOG_ALERT, "update (write) failed for %s: %m", filename); return PAM_AUTH_ERR; } } - if (fclose(*tfile)) { - *tfile = NULL; - pam_syslog(pamh, LOG_ALERT, "update (fclose) failed for %s: %m", filename); + if (fsync(*tfile)) { + pam_syslog(pamh, LOG_ALERT, "update (fsync) failed for %s: %m", filename); return PAM_AUTH_ERR; } - *tfile=NULL; return PAM_SUCCESS; } @@ -566,20 +621,21 @@ cleanup: static int tally_bump (int inc, time_t *oldtime, pam_handle_t *pamh, - uid_t uid, const char *user, struct tally_options *opts) + uid_t uid, const char *user, struct tally_options *opts, int *tfile) { struct tallylog tally; tally_t oldcnt; - FILE *tfile = NULL; const void *remote_host = NULL; int i, rv; tally.fail_cnt = 0; /* !TALLY_HI --> Log opened for update */ - i = get_tally(pamh, uid, opts->filename, &tfile, &tally); + i = get_tally(pamh, uid, opts->filename, tfile, &tally, opts->ctrl); if (i != PAM_SUCCESS) { - if (tfile) - fclose(tfile); + if (*tfile != -1) { + close(*tfile); + *tfile = -1; + } RETURN_ERROR(i); } @@ -617,23 +673,28 @@ tally_bump (int inc, time_t *oldtime, pam_handle_t *pamh, rv = tally_check(oldcnt, *oldtime, pamh, uid, user, opts, &tally); - i = set_tally(pamh, uid, opts->filename, &tfile, &tally); + i = set_tally(pamh, uid, opts->filename, tfile, &tally); if (i != PAM_SUCCESS) { - if (tfile) - fclose(tfile); + if (*tfile != -1) { + close(*tfile); + *tfile = -1; + } if (rv == PAM_SUCCESS) RETURN_ERROR( i ); /* fallthrough */ + } else if (!(opts->ctrl & OPT_SERIALIZE)) { + close(*tfile); + *tfile = -1; } return rv; } static int -tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts) +tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts, int old_tfile) { struct tallylog tally; - FILE *tfile = NULL; + int tfile = old_tfile; int i; /* resets only if not magic root */ @@ -644,10 +705,10 @@ tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts) tally.fail_cnt = 0; /* !TALLY_HI --> Log opened for update */ - i=get_tally(pamh, uid, opts->filename, &tfile, &tally); + i=get_tally(pamh, uid, opts->filename, &tfile, &tally, opts->ctrl); if (i != PAM_SUCCESS) { - if (tfile) - fclose(tfile); + if (tfile != old_tfile) /* the descriptor is not owned by pam data */ + close(tfile); RETURN_ERROR(i); } @@ -655,11 +716,14 @@ tally_reset (pam_handle_t *pamh, uid_t uid, struct tally_options *opts) i=set_tally(pamh, uid, opts->filename, &tfile, &tally); if (i != PAM_SUCCESS) { - if (tfile) - fclose(tfile); + if (tfile != old_tfile) /* the descriptor is not owned by pam data */ + close(tfile); RETURN_ERROR(i); } + if (tfile != old_tfile) + close(tfile); + return PAM_SUCCESS; } @@ -672,7 +736,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { int - rv; + rv, tfile = -1; time_t oldtime = 0; struct tally_options @@ -693,9 +757,9 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, if (rv != PAM_SUCCESS) RETURN_ERROR(rv); - rv = tally_bump(1, &oldtime, pamh, uid, user, opts); + rv = tally_bump(1, &oldtime, pamh, uid, user, opts, &tfile); - tally_set_data(pamh, oldtime); + tally_set_data(pamh, oldtime, tfile); return rv; } @@ -705,7 +769,7 @@ pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { int - rv; + rv, tfile = -1; time_t oldtime = 0; struct tally_options @@ -723,11 +787,15 @@ pam_sm_setcred(pam_handle_t *pamh, int flags UNUSED, if ( rv != PAM_SUCCESS ) RETURN_ERROR( rv ); - if ( tally_get_data(pamh, &oldtime) != 0 ) + if ( tally_get_data(pamh, &oldtime, &tfile) != 0 ) /* no data found */ return PAM_SUCCESS; - return tally_reset(pamh, uid, opts); + rv = tally_reset(pamh, uid, opts, tfile); + + pam_set_data(pamh, MODULE_NAME, NULL, NULL); + + return rv; } /*---------------------------------------------------------------------*/ @@ -741,7 +809,7 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { int - rv; + rv, tfile = -1; time_t oldtime = 0; struct tally_options @@ -759,11 +827,15 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, if ( rv != PAM_SUCCESS ) RETURN_ERROR( rv ); - if ( tally_get_data(pamh, &oldtime) != 0 ) + if ( tally_get_data(pamh, &oldtime, &tfile) != 0 ) /* no data found */ return PAM_SUCCESS; - return tally_reset(pamh, uid, opts); + rv = tally_reset(pamh, uid, opts, tfile); + + pam_set_data(pamh, MODULE_NAME, NULL, NULL); + + return rv; } /*-----------------------------------------------------------------------*/ @@ -895,7 +967,7 @@ main( int argc UNUSED, char **argv ) if ( cline_user ) { uid_t uid; - FILE *tfile=0; + int tfile = -1; struct tally_options opts; int i; @@ -907,10 +979,10 @@ main( int argc UNUSED, char **argv ) exit(1); } - i=get_tally(NULL, uid, cline_filename, &tfile, &tally); + i=get_tally(NULL, uid, cline_filename, &tfile, &tally, 0); if ( i != PAM_SUCCESS ) { - if (tfile) - fclose(tfile); + if (tfile != -1) + close(tfile); fprintf(stderr, "%s: %s\n", *argv, pam_errors(i)); exit(1); } @@ -934,13 +1006,13 @@ main( int argc UNUSED, char **argv ) tally.fail_cnt = cline_reset; } i=set_tally(NULL, uid, cline_filename, &tfile, &tally); + close(tfile); if (i != PAM_SUCCESS) { - if (tfile) fclose(tfile); fprintf(stderr,"%s: %s\n",*argv,pam_errors(i)); exit(1); } } else { - fclose(tfile); + close(tfile); } } else /* !cline_user (ie, operate on all users) */ { diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c index 40ff3c06..f8698337 100644 --- a/modules/pam_unix/pam_unix_acct.c +++ b/modules/pam_unix/pam_unix_acct.c @@ -65,7 +65,7 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, const char *user, int *daysleft) { int retval=0, child, fds[2]; - void (*sighandler)(int) = NULL; + struct sigaction newsa, oldsa; D(("running verify_binary")); /* create a pipe for the messages */ @@ -85,7 +85,9 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, * The "noreap" module argument is provided so that the admin can * override this behavior. */ - sighandler = signal(SIGCHLD, SIG_DFL); + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &newsa, &oldsa); } /* fork */ @@ -158,9 +160,11 @@ int _unix_run_verify_binary(pam_handle_t *pamh, unsigned int ctrl, } close(fds[0]); } - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ + + if (off(UNIX_NOREAP, ctrl)) { + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ } + D(("Returning %d",retval)); return retval; } diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c index b8da9913..9386d87f 100644 --- a/modules/pam_unix/pam_unix_passwd.c +++ b/modules/pam_unix/pam_unix_passwd.c @@ -139,7 +139,7 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const const char *fromwhat, const char *towhat, int remember) { int retval, child, fds[2]; - void (*sighandler)(int) = NULL; + struct sigaction newsa, oldsa; D(("called.")); /* create a pipe for the password */ @@ -157,7 +157,9 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const * The "noreap" module argument is provided so that the admin can * override this behavior. */ - sighandler = signal(SIGCHLD, SIG_DFL); + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &newsa, &oldsa); } /* fork */ @@ -236,8 +238,8 @@ static int _unix_run_update_binary(pam_handle_t *pamh, unsigned int ctrl, const retval = PAM_AUTH_ERR; } - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ + if (off(UNIX_NOREAP, ctrl)) { + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ } return retval; diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index 360bd90b..234e86dd 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -994,8 +994,12 @@ su_sighandler(int sig) { #ifndef SA_RESETHAND /* emulate the behaviour of the SA_RESETHAND flag */ - if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) - signal(sig, SIG_DFL); + if ( sig == SIGILL || sig == SIGTRAP || sig == SIGBUS || sig = SIGSERV ) { + struct sigaction sa; + memset(&sa, '\0, sizeof(sa)); + sa.sa_handler = SIG_DFL; + sigaction(sig, &sa, NULL); + } #endif if (sig > 0) { _exit(sig); diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c index faec20dc..6e1bd454 100644 --- a/modules/pam_unix/support.c +++ b/modules/pam_unix/support.c @@ -408,7 +408,7 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, unsigned int ctrl, const char *user) { int retval, child, fds[2]; - void (*sighandler)(int) = NULL; + struct sigaction newsa, oldsa; D(("called.")); /* create a pipe for the password */ @@ -426,7 +426,9 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, * The "noreap" module argument is provided so that the admin can * override this behavior. */ - sighandler = signal(SIGCHLD, SIG_DFL); + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &newsa, &oldsa); } /* fork */ @@ -497,8 +499,8 @@ static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd, retval = PAM_AUTH_ERR; } - if (sighandler != SIG_ERR) { - (void) signal(SIGCHLD, sighandler); /* restore old signal handler */ + if (off(UNIX_NOREAP, ctrl)) { + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ } D(("returning %d", retval)); |