summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG5
-rw-r--r--doc/Makefile4
-rw-r--r--doc/pam_appl.sgml7
-rw-r--r--libpam/pam_env.c2
-rw-r--r--libpam/pam_item.c14
-rw-r--r--modules/pam_filter/pam_filter.c13
-rw-r--r--modules/pam_filter/upperLOWER/Makefile7
-rw-r--r--modules/pam_filter/upperLOWER/upperLOWER.c15
-rw-r--r--modules/pam_ftp/pam_ftp.c4
-rw-r--r--modules/pam_group/pam_group.c8
-rw-r--r--modules/pam_issue/pam_issue.c29
-rw-r--r--modules/pam_lastlog/pam_lastlog.c8
-rw-r--r--modules/pam_limits/pam_limits.c48
-rw-r--r--modules/pam_mail/pam_mail.c18
-rw-r--r--modules/pam_mkhomedir/pam_mkhomedir.c38
-rw-r--r--modules/pam_motd/pam_motd.c38
-rw-r--r--modules/pam_nologin/pam_nologin.c35
-rw-r--r--modules/pam_permit/pam_permit.c4
-rw-r--r--modules/pam_shells/pam_shells.c11
-rw-r--r--modules/pam_stress/pam_stress.c71
-rw-r--r--modules/pam_tally/pam_tally.c9
-rw-r--r--modules/pam_time/pam_time.c4
-rw-r--r--modules/pam_unix/pam_unix_auth.c11
-rw-r--r--modules/pam_wheel/pam_wheel.c2
-rw-r--r--modules/pammodutil/Makefile2
-rw-r--r--modules/pammodutil/include/security/_pam_modutil.h4
-rw-r--r--modules/pammodutil/modutil_ioloop.c50
27 files changed, 312 insertions, 149 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 8a2092d8..d170c706 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -103,8 +103,9 @@ BerliOS Bugs are marked with (BerliOS #XXXX).
(from Linux distributors - kukuk)
* pam_unix/pam_pwdb: Use SIG_DFL instead of SIG_IGN for SIGCHLD
(from Linux distributors - kukuk)
-* Add parts of the first chunk of Steve Grubb's resource leak and
- other fixes (from Linux distributors - kukuk)
+* Add most of Steve Grubb's resource leak and other fixes (from
+ Linux distributors - kukuk)
+* doc/Makefile: Don't include .cvsignore files in tar ball (kukuk)
0.77: Mon Sep 23 10:25:42 PDT 2002
diff --git a/doc/Makefile b/doc/Makefile
index 081864ac..b7475694 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -152,7 +152,9 @@ spec: specs/draft-morgan-pam.raw
specs/formatter/padout < specs/draft-morgan-pam.raw > specs/draft-morgan-pam-current.txt
releasedocs: all spec
- tar zvfc Linux-PAM-$(MAJOR_REL).$(MINOR_REL)-docs.tar.gz --exclude CVS html ps txts specs/draft-morgan-pam-current.txt
+ tar zvfc Linux-PAM-$(MAJOR_REL).$(MINOR_REL)-docs.tar.gz \
+ --exclude CVS --exclude .cvsignore --exclude '.#*' \
+ html ps txts specs/draft-morgan-pam-current.txt
clean:
rm -f *~ *.bak
diff --git a/doc/pam_appl.sgml b/doc/pam_appl.sgml
index 85a878a0..87cb83f1 100644
--- a/doc/pam_appl.sgml
+++ b/doc/pam_appl.sgml
@@ -442,12 +442,7 @@ However, the application should expect one of the following errors:
</descrip>
<p>
-Note, in the case of an error, the contents of <tt/item/ is not
-modified - that is, it retains its pre-call value. One should take
-care to initialize this value prior to calling
-<tt/pam_get_item()/. Since, if its value - despite the
-<tt/pam_get_item()/ function failing - is to be used the consequences
-are undefined.
+In the case of an error, the contents of <tt/item/ is set to <tt/NULL/.
<sect2>Understanding errors
<label id="pam-strerror-section">
diff --git a/libpam/pam_env.c b/libpam/pam_env.c
index ae1ddf2e..0e08cbdd 100644
--- a/libpam/pam_env.c
+++ b/libpam/pam_env.c
@@ -344,7 +344,7 @@ static char **_copy_env(pam_handle_t *pamh)
_pam_overwrite(dump[i]);
_pam_drop(dump[i]);
}
- __pam_drop(dump);
+ _pam_drop(dump);
return NULL;
}
}
diff --git a/libpam/pam_item.c b/libpam/pam_item.c
index 47686411..230f5068 100644
--- a/libpam/pam_item.c
+++ b/libpam/pam_item.c
@@ -158,6 +158,8 @@ int pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
"pam_get_item: nowhere to place requested item");
return PAM_PERM_DENIED;
}
+ else
+ *item = NULL;
switch (item_type) {
case PAM_SERVICE:
@@ -238,6 +240,12 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
struct pam_response *resp;
D(("called."));
+ if (user == NULL) { /* ensure that the module has supplied a destination */
+ _pam_system_log(LOG_ERR, "pam_get_user: nowhere to record username");
+ return PAM_PERM_DENIED;
+ } else
+ *user = NULL;
+
IF_NO_PAMH("pam_get_user", pamh, PAM_SYSTEM_ERR);
if (pamh->pam_conversation == NULL) {
@@ -245,12 +253,6 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
return PAM_SERVICE_ERR;
}
- if (user == NULL) { /* ensure the the module has suplied a destination */
- _pam_system_log(LOG_ERR, "pam_get_user: nowhere to record username");
- return PAM_PERM_DENIED;
- } else
- *user = NULL;
-
if (pamh->user) { /* have one so return it */
*user = pamh->user;
return PAM_SUCCESS;
diff --git a/modules/pam_filter/pam_filter.c b/modules/pam_filter/pam_filter.c
index 9a6fc8c5..e9a0494b 100644
--- a/modules/pam_filter/pam_filter.c
+++ b/modules/pam_filter/pam_filter.c
@@ -131,7 +131,7 @@ static int process_args(pam_handle_t *pamh
} else {
char **levp;
const char *tmp;
- int i,size;
+ int i,size, retval;
*filtername = *++argv;
if (ctrl & FILTER_DEBUG) {
@@ -177,7 +177,15 @@ static int process_args(pam_handle_t *pamh
#define SERVICE_OFFSET 8 /* sizeof('SERVICE='); */
#define SERVICE_NAME "SERVICE="
- pam_get_item(pamh, PAM_SERVICE, (const void **)&tmp);
+ retval = pam_get_item(pamh, PAM_SERVICE, (const void **)&tmp);
+ if (retval != PAM_SUCCESS || tmp == NULL) {
+ _pam_log(LOG_CRIT,"service name not found");
+ if (levp) {
+ free(levp[0]);
+ free(levp);
+ }
+ return -1;
+ }
size = SERVICE_OFFSET+strlen(tmp);
levp[1] = (char *) malloc(size+1);
@@ -199,6 +207,7 @@ static int process_args(pam_handle_t *pamh
#define USER_OFFSET 5 /* sizeof('USER='); */
#define USER_NAME "USER="
+ tmp = NULL;
pam_get_user(pamh, &tmp, NULL);
if (tmp == NULL) {
tmp = "<unknown>";
diff --git a/modules/pam_filter/upperLOWER/Makefile b/modules/pam_filter/upperLOWER/Makefile
index 77bc4102..60c6d08c 100644
--- a/modules/pam_filter/upperLOWER/Makefile
+++ b/modules/pam_filter/upperLOWER/Makefile
@@ -12,16 +12,19 @@ TITLE=upperLOWER
#
-CFLAGS += -I../include
+CFLAGS += -I../include -I../../pammodutil/include
OBJS = $(TITLE).o
+LIBS += $(GLIB_LIBS) -L../../pammodutil -lpammodutil
+LDFLAGS = $(LIBS)
+
####################### don't edit below #######################
all: $(TITLE)
$(TITLE): $(OBJS)
- $(CC) $(CFLAGS) -o $(TITLE) $(OBJS)
+ $(CC) $(CFLAGS) -o $(TITLE) $(OBJS) $(LDFLAGS)
$(STRIP) $(TITLE)
install:
diff --git a/modules/pam_filter/upperLOWER/upperLOWER.c b/modules/pam_filter/upperLOWER/upperLOWER.c
index e750e877..72f9dab5 100644
--- a/modules/pam_filter/upperLOWER/upperLOWER.c
+++ b/modules/pam_filter/upperLOWER/upperLOWER.c
@@ -21,6 +21,9 @@
#include <unistd.h>
#include <security/pam_filter.h>
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+#include <security/_pam_modutil.h>
/* ---------------------------------------------------------------- */
@@ -109,27 +112,27 @@ int main(int argc, char **argv)
/* application errors */
if ( FD_ISSET(APPERR_FILENO,&readers) ) {
- int got = read(APPERR_FILENO, buffer, BUFSIZ);
+ int got = _pammodutil_read(APPERR_FILENO, buffer, BUFSIZ);
if (got <= 0) {
break;
} else {
/* translate to give to real terminal */
if (before_user != NULL)
before_user(buffer, got);
- if ( write(STDERR_FILENO, buffer, got) != got ) {
+ if (_pammodutil_write(STDERR_FILENO, buffer, got) != got ) {
log_this(LOG_WARNING,"couldn't write %d bytes?!",got);
break;
}
}
} else if ( FD_ISSET(APPOUT_FILENO,&readers) ) { /* app output */
- int got = read(APPOUT_FILENO, buffer, BUFSIZ);
+ int got = _pammodutil_read(APPOUT_FILENO, buffer, BUFSIZ);
if (got <= 0) {
break;
} else {
/* translate to give to real terminal */
if (before_user != NULL)
before_user(buffer, got);
- if ( write(STDOUT_FILENO, buffer, got) != got ) {
+ if (_pammodutil_write(STDOUT_FILENO, buffer, got) != got ) {
log_this(LOG_WARNING,"couldn't write %d bytes!?",got);
break;
}
@@ -137,7 +140,7 @@ int main(int argc, char **argv)
}
if ( FD_ISSET(STDIN_FILENO, &readers) ) { /* user input */
- int got = read(STDIN_FILENO, buffer, BUFSIZ);
+ int got = _pammodutil_read(STDIN_FILENO, buffer, BUFSIZ);
if (got < 0) {
log_this(LOG_WARNING,"user input junked");
break;
@@ -145,7 +148,7 @@ int main(int argc, char **argv)
/* translate to give to application */
if (before_app != NULL)
before_app(buffer, got);
- if ( write(APPIN_FILENO, buffer, got) != got ) {
+ if (_pammodutil_write(APPIN_FILENO, buffer, got) != got ) {
log_this(LOG_WARNING,"couldn't pass %d bytes!?",got);
break;
}
diff --git a/modules/pam_ftp/pam_ftp.c b/modules/pam_ftp/pam_ftp.c
index bebcd2b2..e95b7d78 100644
--- a/modules/pam_ftp/pam_ftp.c
+++ b/modules/pam_ftp/pam_ftp.c
@@ -58,7 +58,7 @@ static int converse(pam_handle_t *pamh, int nargs
D(("begin to converse\n"));
retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
- if ( retval == PAM_SUCCESS ) {
+ if ( retval == PAM_SUCCESS && conv ) {
retval = conv->conv(nargs, ( const struct pam_message ** ) message
, response, conv->appdata_ptr);
@@ -73,6 +73,8 @@ static int converse(pam_handle_t *pamh, int nargs
} else {
_pam_log(LOG_ERR, "couldn't obtain coversation function [%s]"
, pam_strerror(pamh, retval));
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was NULL */
}
D(("ready to return from module conversation\n"));
diff --git a/modules/pam_group/pam_group.c b/modules/pam_group/pam_group.c
index 77c909d0..4b42506c 100644
--- a/modules/pam_group/pam_group.c
+++ b/modules/pam_group/pam_group.c
@@ -79,6 +79,12 @@ static void shift_bytes(char *mem, int from, int by)
}
}
+/* This function should initially be called with buf = NULL. If
+ * an error occurs, the file descriptor is closed. Subsequent
+ * calls with a closed descriptor will cause buf to be deallocated.
+ * Therefore, always check buf after calling this to see if an error
+ * occurred.
+ */
static int read_field(int fd, char **buf, int *from, int *to)
{
/* is buf set ? */
@@ -126,6 +132,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
i = read(fd, *to + *buf, PAM_GROUP_BUFLEN - *to);
if (i < 0) {
_log_err("error reading " PAM_GROUP_CONF);
+ close(fd);
return -1;
} else if (!i) {
close(fd);
@@ -165,6 +172,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
} else {
_log_err("internal error in " __FILE__
" at line %d", __LINE__ );
+ close(fd);
return -1;
}
break;
diff --git a/modules/pam_issue/pam_issue.c b/modules/pam_issue/pam_issue.c
index 985bfebc..5665966e 100644
--- a/modules/pam_issue/pam_issue.c
+++ b/modules/pam_issue/pam_issue.c
@@ -84,12 +84,19 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
if ((fd = fopen(issue_file, "r")) != NULL) {
int tot_size = 0;
- if (fstat(fileno(fd), &st) < 0)
+ if (fstat(fileno(fd), &st) < 0) {
+ fclose(fd);
+ if (issue_file)
+ free(issue_file);
return PAM_IGNORE;
+ }
retval = pam_get_item(pamh, PAM_USER_PROMPT,
(const void **) &cur_prompt);
if (retval != PAM_SUCCESS) {
+ fclose(fd);
+ if (issue_file)
+ free(issue_file);
return PAM_IGNORE;
}
if (cur_prompt == NULL) {
@@ -101,6 +108,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
if (parse_esc) {
prompt_tmp = do_prompt(fd);
if (prompt_tmp == NULL) {
+ fclose(fd);
+ if (issue_file)
+ free(issue_file);
return PAM_IGNORE;
}
} else {
@@ -108,13 +118,17 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
prompt_tmp = malloc(st.st_size + 1);
if (prompt_tmp == NULL) {
+ fclose(fd);
+ if (issue_file)
+ free(issue_file);
return PAM_IGNORE;
}
memset (prompt_tmp, '\0', st.st_size + 1);
count = fread(prompt_tmp, 1, st.st_size, fd);
if (count != st.st_size) {
- free(prompt_tmp);
- return PAM_IGNORE;
+ fclose(fd);
+ retval = PAM_IGNORE;
+ goto cleanup;
}
prompt_tmp[st.st_size] = '\0';
}
@@ -151,6 +165,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
} else {
D(("could not open issue_file: %s", issue_file));
+ free(issue_file);
return PAM_IGNORE;
}
@@ -167,11 +182,15 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
static char *do_prompt(FILE *fd)
{
int c, size = 1024;
- char *issue = (char *)malloc(size);
+ char *issue;
char buf[1024];
struct utsname uts;
- if (issue == NULL || fd == NULL)
+ if (fd == NULL)
+ return NULL;
+
+ issue = (char *)malloc(size);
+ if (issue == NULL)
return NULL;
issue[0] = '\0'; /* zero this, for strcat to work on first buf */
diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c
index f9a730bf..1e7a3b4f 100644
--- a/modules/pam_lastlog/pam_lastlog.c
+++ b/modules/pam_lastlog/pam_lastlog.c
@@ -149,7 +149,7 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
D(("begin to converse"));
retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
- if ( retval == PAM_SUCCESS ) {
+ if ( retval == PAM_SUCCESS && conv) {
retval = conv->conv(nargs, ( const struct pam_message ** ) message
, response, conv->appdata_ptr);
@@ -164,6 +164,8 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
} else {
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
, pam_strerror(pamh, retval));
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was NULL */
}
D(("ready to return from module conversation"));
@@ -235,7 +237,7 @@ static int last_login_date(pam_handle_t *pamh, int announce, uid_t uid)
sleep(LASTLOG_IGNORE_LOCK_TIME);
}
- win = ( read(last_fd, &last_login, sizeof(last_login))
+ win = ( _pammodutil_read(last_fd, &last_login, sizeof(last_login))
== sizeof(last_login) );
last_lock.l_type = F_UNLCK;
@@ -376,7 +378,7 @@ static int last_login_date(pam_handle_t *pamh, int announce, uid_t uid)
}
D(("writing to the last_log file"));
- (void) write(last_fd, &last_login, sizeof(last_login));
+ (void) _pammodutil_write(last_fd, &last_login, sizeof(last_login));
last_lock.l_type = F_UNLCK;
(void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c
index 6837fdef..0d7f2185 100644
--- a/modules/pam_limits/pam_limits.c
+++ b/modules/pam_limits/pam_limits.c
@@ -1,13 +1,13 @@
/*
* pam_limits - impose resource limits when opening a user session
*
- * 1.6 - modified for PLD (added process priority settings)
+ * 1.6 - modified for PLD (added process priority settings)
* by Marcin Korzonek <mkorz@shadow.eu.org>
* 1.5 - Elliot Lee's "max system logins patch"
* 1.4 - addressed bug in configuration file parser
* 1.3 - modified the configuration file format
* 1.2 - added 'debug' and 'conf=' arguments
- * 1.1 - added @group support
+ * 1.1 - added @group support
* 1.0 - initial release - Linux ONLY
*
* See end for Copyright information
@@ -15,7 +15,7 @@
#if !(defined(linux))
#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
-#endif
+#endif
#include <security/_pam_aconf.h>
@@ -54,6 +54,8 @@ static const char *limits_def_names[] = {
"GROUP",
"DEFAULT",
"NONE",
+ "ALL",
+ "ALLGROUP",
NULL,
};
@@ -165,7 +167,7 @@ static int is_in_group(const char *user_name, const char *group_name)
struct passwd *pwd;
struct group *grp, *pgrp;
char uname[LINE_LENGTH], gname[LINE_LENGTH];
-
+
if (!user_name || !strlen(user_name))
return 0;
if (!group_name || !strlen(group_name))
@@ -174,7 +176,7 @@ static int is_in_group(const char *user_name, const char *group_name)
strncpy(uname, user_name, sizeof(uname)-1);
memset(gname, 0, sizeof(gname));
strncpy(gname, group_name, sizeof(gname)-1);
-
+
pwd = getpwnam(uname);
if (!pwd)
return 0;
@@ -183,7 +185,7 @@ static int is_in_group(const char *user_name, const char *group_name)
grp = getgrnam(gname);
if (!grp)
return 0;
-
+
/* first check: is a member of the group_name group ? */
if (is_on_list(grp->gr_mem, uname))
return 1;
@@ -194,10 +196,10 @@ static int is_in_group(const char *user_name, const char *group_name)
return 0;
if (!strcmp(pgrp->gr_name, gname))
return 1;
-
+
return 0;
}
-
+
/* Counts the number of user logins and check against the limit*/
static int check_logins(const char *name, int limit, int ctrl,
struct pam_limit_s *pl)
@@ -228,7 +230,7 @@ static int check_logins(const char *name, int limit, int ctrl,
standard for this, since if a module wants to actually map a
username then any early utmp entry will be for the unmapped
name = broken.) */
-
+
if (ctrl & PAM_UTMP_EARLY) {
count = 0;
} else {
@@ -300,7 +302,7 @@ static int init_limits(struct pam_limit_s *pl)
pl->login_limit_def = LIMITS_DEF_NONE;
return retval;
-}
+}
static void process_limit(int source, const char *lim_type,
const char *lim_item, const char *lim_value,
@@ -311,7 +313,7 @@ static void process_limit(int source, const char *lim_type,
long limit_value;
const char **endptr = &lim_value;
const char *value_orig = lim_value;
-
+
if (ctrl & PAM_DEBUG_ARG)
_pam_log(LOG_DEBUG, "%s: processing %s %s %s for %s\n",
__FUNCTION__,lim_type,lim_item,lim_value,
@@ -451,7 +453,7 @@ static int parse_config_file(const char *uname, int ctrl,
{
FILE *fil;
char buf[LINE_LENGTH];
-
+
#define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE
/* check for the LIMITS_FILE */
if (ctrl & PAM_DEBUG_ARG)
@@ -462,7 +464,7 @@ static int parse_config_file(const char *uname, int ctrl,
return PAM_SERVICE_ERR;
}
#undef CONF_FILE
-
+
/* init things */
memset(buf, 0, sizeof(buf));
/* start the show */
@@ -473,14 +475,14 @@ static int parse_config_file(const char *uname, int ctrl,
char value[LINE_LENGTH];
int i,j;
char *tptr;
-
+
tptr = buf;
/* skip the leading white space */
while (*tptr && isspace(*tptr))
tptr++;
strncpy(buf, tptr, sizeof(buf)-1);
buf[sizeof(buf)-1] = '\0';
-
+
/* Rip off the comments */
tptr = strchr(buf,'#');
if (tptr)
@@ -499,7 +501,7 @@ static int parse_config_file(const char *uname, int ctrl,
memset(ltype, 0, sizeof(ltype));
memset(item, 0, sizeof(item));
memset(value, 0, sizeof(value));
-
+
i = sscanf(buf,"%s%s%s%s", domain, ltype, item, value);
D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]",
i, domain, ltype, item, value));
@@ -558,7 +560,7 @@ static int parse_config_file(const char *uname, int ctrl,
}
}
fclose(fil);
- return PAM_SUCCESS;
+ return PAM_SUCCESS;
}
static int setup_limits(const char * uname, uid_t uid, int ctrl,
@@ -588,7 +590,7 @@ static int setup_limits(const char * uname, uid_t uid, int ctrl,
}
status |= setrlimit(i, &pl->limits[i].limit);
}
-
+
if (status) {
retval = LIMIT_ERR;
}
@@ -610,7 +612,7 @@ static int setup_limits(const char * uname, uid_t uid, int ctrl,
return retval;
}
-
+
/* now the session stuff */
PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char **argv)
@@ -631,7 +633,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
_pam_log(LOG_CRIT, "open_session - error recovering username");
return PAM_SESSION_ERR;
}
-
+
pwd = getpwnam(user_name);
if (!pwd) {
if (ctrl & PAM_DEBUG_ARG)
@@ -639,7 +641,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
user_name);
return PAM_SESSION_ERR;
}
-
+
retval = init_limits(&pl);
if (retval != PAM_SUCCESS) {
_pam_log(LOG_WARNING, "cannot initialize");
@@ -705,13 +707,13 @@ struct pam_module _pam_limits_modstruct = {
* 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
diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c
index 35a6b9f2..4888a1a5 100644
--- a/modules/pam_mail/pam_mail.c
+++ b/modules/pam_mail/pam_mail.c
@@ -32,7 +32,7 @@
#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s"
#define YOUR_MAIL_VERBOSE_FORMAT "You have %s mail in %s."
#define YOUR_MAIL_STANDARD_FORMAT "You have %smail."
-#define NO_MAIL_STANDARD_FORMAT "No mail."
+#define NO_MAIL_STANDARD_FORMAT "No mail."
/*
* here, we make a definition for the externally accessible function
@@ -142,8 +142,8 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
D(("begin to converse"));
- retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
- if ( retval == PAM_SUCCESS ) {
+ retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
+ if ( retval == PAM_SUCCESS && conv ) {
retval = conv->conv(nargs, ( const struct pam_message ** ) message
, response, conv->appdata_ptr);
@@ -158,6 +158,8 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
} else {
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
, pam_strerror(pamh, retval));
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was NULL */
}
D(("ready to return from module conversation"));
@@ -234,7 +236,9 @@ static int get_folder(pam_handle_t *pamh, int ctrl,
_pam_overwrite(hash);
_pam_drop(hash);
} else {
- sprintf(folder, "error");
+ _pam_drop(folder);
+ _log_err(LOG_CRIT, "out of memory for mail folder");
+ return PAM_BUF_ERR;
}
}
D(("folder =[%s]", folder));
@@ -386,7 +390,7 @@ PAM_EXTERN
int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
- return _do_mail(pamh,flags,argc,argv,0);;
+ return _do_mail(pamh,flags,argc,argv,0);
}
/* Checking mail as part of the session management */
@@ -467,8 +471,8 @@ static int _do_mail(pam_handle_t *pamh, int flags, int argc,
type = NULL;
}
}
-
- /* Delete environment variable? */
+
+ /* Delete environment variable? */
if (!est)
(void) pam_putenv(pamh, MAIL_ENV_NAME);
diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c
index c6d49301..342637c1 100644
--- a/modules/pam_mkhomedir/pam_mkhomedir.c
+++ b/modules/pam_mkhomedir/pam_mkhomedir.c
@@ -111,7 +111,7 @@ static int converse(pam_handle_t * pamh, int ctrl, int nargs
D(("begin to converse"));
retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
- if (retval == PAM_SUCCESS)
+ if (retval == PAM_SUCCESS && conv)
{
retval = conv->conv(nargs, (const struct pam_message **) message
@@ -130,6 +130,8 @@ static int converse(pam_handle_t * pamh, int ctrl, int nargs
{
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
,pam_strerror(pamh, retval));
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was NULL */
}
D(("ready to return from module conversation"));
@@ -235,7 +237,11 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
/* If it's a directory, recurse. */
if (S_ISDIR(St.st_mode))
{
- create_homedir(pamh, ctrl, pwd, newsource, newdest);
+ int retval = create_homedir(pamh, ctrl, pwd, newsource, newdest);
+ if (retval != PAM_SUCCESS) {
+ closedir(D);
+ return retval;
+ }
continue;
}
@@ -250,6 +256,7 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
{
if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0)
{
+ closedir(D);
_log_err(LOG_DEBUG, "unable to chang perms on link %s",
newdest);
return PAM_PERM_DENIED;
@@ -269,6 +276,7 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
/* Open the source file */
if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0)
{
+ closedir(D);
_log_err(LOG_DEBUG, "unable to open src file %s",newsource);
return PAM_PERM_DENIED;
}
@@ -278,6 +286,7 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0)
{
close(SrcFd);
+ closedir(D);
_log_err(LOG_DEBUG, "unable to open dest file %s",newdest);
return PAM_PERM_DENIED;
}
@@ -290,6 +299,7 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
{
close(SrcFd);
close(DestFd);
+ closedir(D);
_log_err(LOG_DEBUG, "unable to chang perms on copy %s",newdest);
return PAM_PERM_DENIED;
}
@@ -297,19 +307,29 @@ static int create_homedir(pam_handle_t * pamh, int ctrl,
/* Copy the file */
do
{
- Res = read(SrcFd,remark,sizeof(remark));
- if (Res < 0 || write(DestFd,remark,Res) != Res)
- {
- close(SrcFd);
- close(DestFd);
- _log_err(LOG_DEBUG, "unable to perform IO");
- return PAM_PERM_DENIED;
+ Res = _pammodutil_read(SrcFd,remark,sizeof(remark));
+
+ if (Res == 0)
+ continue;
+
+ if (Res > 0) {
+ if (_pammodutil_write(DestFd,remark,Res) == Res)
+ continue;
}
+
+ /* If we get here, pammodutil_read returned a -1 or
+ _pammodutil_write returned something unexpected. */
+ close(SrcFd);
+ close(DestFd);
+ closedir(D);
+ _log_err(LOG_DEBUG, "unable to perform IO");
+ return PAM_PERM_DENIED;
}
while (Res != 0);
close(SrcFd);
close(DestFd);
}
+ closedir(D);
return PAM_SUCCESS;
}
diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c
index 759cc017..b1d9c9d9 100644
--- a/modules/pam_motd/pam_motd.c
+++ b/modules/pam_motd/pam_motd.c
@@ -33,6 +33,7 @@
#define DEFAULT_MOTD "/etc/motd"
#include <security/pam_modules.h>
+#include <security/_pam_modutil.h>
/* --- session management functions (only) --- */
@@ -80,24 +81,33 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
if ((fd = open(motd_path, O_RDONLY, 0)) >= 0) {
/* fill in message buffer with contents of motd */
- if ((fstat(fd, &st) < 0) || !st.st_size)
+ if ((fstat(fd, &st) < 0) || !st.st_size) {
+ close(fd);
return retval;
+ }
message.msg = mtmp = malloc(st.st_size+1);
/* if malloc failed... */
- if (!message.msg) return retval;
- read(fd, mtmp, st.st_size);
- if (mtmp[st.st_size-1] == '\n')
- mtmp[st.st_size-1] = '\0';
- else
- mtmp[st.st_size] = '\0';
- close(fd);
- /* Use conversation function to give user contents of motd */
- pam_get_item(pamh, PAM_CONV, (const void **)&conversation);
- conversation->conv(1, (const struct pam_message **)&pmessage,
- &resp, conversation->appdata_ptr);
+ if (!message.msg) {
+ close(fd);
+ return retval;
+ }
+ if (_pammodutil_read(fd, mtmp, st.st_size) == st.st_size) {
+ if (mtmp[st.st_size-1] == '\n')
+ mtmp[st.st_size-1] = '\0';
+ else
+ mtmp[st.st_size] = '\0';
+ close(fd);
+
+ /* Use conversation function to give user contents of motd */
+ if (pam_get_item(pamh, PAM_CONV, (const void **)&conversation) ==
+ PAM_SUCCESS && conversation) {
+ conversation->conv(1, (const struct pam_message **)&pmessage,
+ &resp, conversation->appdata_ptr);
+ if (resp)
+ _pam_drop_reply(resp, 1);
+ }
+ }
free(mtmp);
- if (resp)
- _pam_drop_reply(resp, 1);
}
return retval;
diff --git a/modules/pam_nologin/pam_nologin.c b/modules/pam_nologin/pam_nologin.c
index 6916a7b4..433d2e11 100644
--- a/modules/pam_nologin/pam_nologin.c
+++ b/modules/pam_nologin/pam_nologin.c
@@ -117,22 +117,31 @@ static int perform_check(pam_handle_t *pamh, struct opt_s *opts)
goto clean_up_fd;
}
- read(fd, mtmp, st.st_size);
- mtmp[st.st_size] = '\000';
-
- /*
- * Use conversation function to give user contents of /etc/nologin
- */
+ if (_pammodutil_read(fd, mtmp, st.st_size) == st.st_size) {
+ mtmp[st.st_size] = '\000';
+
+ /*
+ * Use conversation function to give user contents
+ * of /etc/nologin
+ */
+
+ retval = pam_get_item(pamh, PAM_CONV,
+ (const void **)&conversation);
+ if ((retval == PAM_SUCCESS) && (conversation)) {
+ (void) conversation->conv(1,
+ (const struct pam_message **)&pmessage,
+ &resp, conversation->appdata_ptr);
+
+ if (resp) {
+ _pam_drop_reply(resp, 1);
+ }
+ }
+ }
+ else
+ retval = PAM_SYSTEM_ERR;
- pam_get_item(pamh, PAM_CONV, (const void **)&conversation);
- (void) conversation->conv(1, (const struct pam_message **)&pmessage,
- &resp, conversation->appdata_ptr);
free(mtmp);
- if (resp) {
- _pam_drop_reply(resp, 1);
- }
-
clean_up_fd:
close(fd);
diff --git a/modules/pam_permit/pam_permit.c b/modules/pam_permit/pam_permit.c
index ea23b312..9eee5611 100644
--- a/modules/pam_permit/pam_permit.c
+++ b/modules/pam_permit/pam_permit.c
@@ -45,7 +45,9 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
}
if (user == NULL || *user == '\0') {
D(("username not known"));
- pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER);
+ retval = pam_set_item(pamh, PAM_USER, (const void *) DEFAULT_USER);
+ if (retval != PAM_SUCCESS)
+ return PAM_USER_UNKNOWN;
}
user = NULL; /* clean up */
diff --git a/modules/pam_shells/pam_shells.c b/modules/pam_shells/pam_shells.c
index 37d740dc..c9e2ed6c 100644
--- a/modules/pam_shells/pam_shells.c
+++ b/modules/pam_shells/pam_shells.c
@@ -59,11 +59,16 @@ static int perform_check(pam_handle_t *pamh, int flags)
return PAM_SERVICE_ERR;
}
- if (!userName || (strlen(userName) <= 0)) {
+ if (!userName || (userName[0] == '\0')) {
+
/* Don't let them use a NULL username... */
- pam_get_user(pamh,&userName,NULL);
+ retval = pam_get_user(pamh,&userName,NULL);
if (retval != PAM_SUCCESS)
return PAM_SERVICE_ERR;
+
+ /* It could still be NULL the second time. */
+ if (!userName || (userName[0] == '\0'))
+ return PAM_SERVICE_ERR;
}
pw = getpwnam(userName);
@@ -93,7 +98,7 @@ static int perform_check(pam_handle_t *pamh, int flags)
retval = 1;
- while((fgets(shellFileLine, 255, shellFile) != NULL) && retval) {
+ while(retval && (fgets(shellFileLine, 255, shellFile) != NULL)) {
if (shellFileLine[strlen(shellFileLine) - 1] == '\n')
shellFileLine[strlen(shellFileLine) - 1] = '\0';
retval = strcmp(shellFileLine, userShell);
diff --git a/modules/pam_stress/pam_stress.c b/modules/pam_stress/pam_stress.c
index 7828f421..d45ad300 100644
--- a/modules/pam_stress/pam_stress.c
+++ b/modules/pam_stress/pam_stress.c
@@ -31,13 +31,6 @@
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
-static char *_strdup(const char *x)
-{
- char *new;
- new = malloc(strlen(x)+1);
- strcpy(new,x);
- return new;
-}
/* log errors */
@@ -141,8 +134,8 @@ static int converse(pam_handle_t *pamh, int nargs
int retval;
struct pam_conv *conv;
- if ((retval = pam_get_item(pamh,PAM_CONV,(const void **)&conv))
- == PAM_SUCCESS) {
+ retval = pam_get_item(pamh,PAM_CONV,(const void **)&conv);
+ if (retval == PAM_SUCCESS && conv) {
retval = conv->conv(nargs, (const struct pam_message **) message
, response, conv->appdata_ptr);
if (retval != PAM_SUCCESS) {
@@ -151,6 +144,8 @@ static int converse(pam_handle_t *pamh, int nargs
}
} else {
_pam_log(LOG_ERR,"(pam_stress) converse failed to get pam_conv");
+ if (retval == PAM_SUCCESS)
+ retval = PAM_BAD_ITEM; /* conv was null */
}
return retval;
@@ -167,7 +162,8 @@ static int stress_get_password(pam_handle_t *pamh, int flags
&& (pam_get_item(pamh,PAM_AUTHTOK,(const void **)&pass)
== PAM_SUCCESS)
&& (pass != NULL) ) {
- pass = _strdup(pass);
+ if ((pass = strdup(pass)) == NULL)
+ return PAM_BUF_ERR;
} else if ((ctrl & PAM_ST_USE_PASS1)) {
_pam_log(LOG_WARNING, "pam_stress: no forwarded password");
return PAM_PERM_DENIED;
@@ -206,7 +202,8 @@ static int stress_get_password(pam_handle_t *pamh, int flags
_pam_log(LOG_DEBUG,"getting password, but NULL returned!?");
return PAM_CONV_ERR;
}
- free(resp);
+ if (resp)
+ free(resp);
}
*password = pass; /* this *MUST* be free()'d by this module */
@@ -238,12 +235,15 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
/* try to get the username */
retval = pam_get_user(pamh, &username, "username: ");
- if ((ctrl & PAM_ST_DEBUG) && (retval == PAM_SUCCESS)) {
- _pam_log(LOG_DEBUG, "pam_sm_authenticate: username = %s", username);
- } else if (retval != PAM_SUCCESS) {
+ if (retval != PAM_SUCCESS || !username) {
_pam_log(LOG_WARNING, "pam_sm_authenticate: failed to get username");
+ if (retval == PAM_SUCCESS)
+ retval = PAM_USER_UNKNOWN; /* username was null */
return retval;
}
+ else if ((ctrl & PAM_ST_DEBUG) && (retval == PAM_SUCCESS)) {
+ _pam_log(LOG_DEBUG, "pam_sm_authenticate: username = %s", username);
+ }
/* now get the password */
@@ -257,20 +257,15 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
/* try to set password item */
retval = pam_set_item(pamh,PAM_AUTHTOK,pass);
+ _pam_overwrite(pass); /* clean up local copy of password */
+ free(pass);
+ pass = NULL;
if (retval != PAM_SUCCESS) {
_pam_log(LOG_WARNING, "pam_sm_authenticate: "
"failed to store new password");
- _pam_overwrite(pass);
- free(pass);
return retval;
}
- /* clean up local copy of password */
-
- _pam_overwrite(pass);
- free(pass);
- pass = NULL;
-
/* if we are debugging then we print the password */
if (ctrl & PAM_ST_DEBUG) {
@@ -319,9 +314,18 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
if (ctrl & PAM_ST_FAIL_1)
return PAM_PERM_DENIED;
else if (ctrl & PAM_ST_EXPIRED) {
- void *text = malloc(sizeof("yes")+1);
- strcpy(text,"yes");
- pam_set_data(pamh,"stress_new_pwd",text,wipe_up);
+ int retval;
+ void *text = strdup("yes");
+ if (!text)
+ return PAM_BUF_ERR;
+ retval = pam_set_data(pamh,"stress_new_pwd",text,wipe_up);
+ if (retval != PAM_SUCCESS) {
+ _pam_log(LOG_DEBUG,
+ "pam_sm_acct_mgmt: failed setting stress_new_pwd");
+ free(text);
+ return retval;
+ }
+
if (ctrl & PAM_ST_DEBUG) {
_pam_log(LOG_DEBUG,"pam_sm_acct_mgmt: need a new password");
}
@@ -343,9 +347,9 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags,
_pam_report(ctrl,"pam_sm_open_session", flags, argc, argv);
if ((pam_get_item(pamh, PAM_USER, (const void **) &username)
- != PAM_SUCCESS)
+ != PAM_SUCCESS || !username)
|| (pam_get_item(pamh, PAM_SERVICE, (const void **) &service)
- != PAM_SUCCESS)) {
+ != PAM_SUCCESS || !service)) {
_pam_log(LOG_WARNING,"pam_sm_open_session: for whom?");
return PAM_SESSION_ERR;
}
@@ -371,9 +375,9 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags,
_pam_report(ctrl,"pam_sm_close_session", flags, argc, argv);
if ((pam_get_item(pamh, PAM_USER, (const void **)&username)
- != PAM_SUCCESS)
+ != PAM_SUCCESS || !username)
|| (pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
- != PAM_SUCCESS)) {
+ != PAM_SUCCESS || !service)) {
_pam_log(LOG_WARNING,"pam_sm_close_session: for whom?");
return PAM_SESSION_ERR;
}
@@ -447,15 +451,14 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
return retval;
}
retval = pam_set_item(pamh, PAM_OLDAUTHTOK, pass);
+ _pam_overwrite(pass);
+ free(pass);
+ pass = NULL;
if (retval != PAM_SUCCESS) {
_pam_log(LOG_DEBUG
,"pam_sm_chauthtok: could not set OLDAUTHTOK");
- _pam_overwrite(pass);
- free(pass);
return retval;
}
- _pam_overwrite(pass);
- free(pass);
}
/* set up for conversation */
@@ -516,7 +519,7 @@ int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
pmsg[0] = &msg[0];
msg[0].msg_style = PAM_ERROR_MSG;
msg[0].msg = "Verification mis-typed; "
- "password unchaged";
+ "password unchanged";
resp = NULL;
(void) converse(pamh,1,pmsg,&resp);
if (resp) {
diff --git a/modules/pam_tally/pam_tally.c b/modules/pam_tally/pam_tally.c
index 3da37f40..27fe0b37 100644
--- a/modules/pam_tally/pam_tally.c
+++ b/modules/pam_tally/pam_tally.c
@@ -109,7 +109,7 @@ static char *cline_user=0; /* cline_user is used in the administration prog */
static int pam_get_uid( pam_handle_t *pamh, uid_t *uid, const char **userp )
{
- const char *user;
+ const char *user = NULL;
struct passwd *pw;
#ifdef MAIN
@@ -189,7 +189,8 @@ static int get_tally( tally_t *tally,
if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) {
_pam_log(LOG_ALERT, "fseek failed %s", filename);
- return PAM_AUTH_ERR;
+ fclose(*TALLY);
+ return PAM_AUTH_ERR;
}
if ( fileinfo.st_size <= uid * sizeof(struct faillog) ) {
@@ -527,6 +528,8 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
user,uid,
fsp->fs_fail_time+fsp->fs_faillog.fail_locktime
-time(NULL));
+ if (TALLY)
+ fclose(TALLY);
return PAM_AUTH_ERR;
}
}
@@ -537,6 +540,8 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
) {
_pam_log(LOG_NOTICE,"user %s ("UID_FMT") tally "TALLY_FMT", deny "TALLY_FMT,
user, uid, tally, deny);
+ if (TALLY)
+ fclose(TALLY);
return PAM_AUTH_ERR; /* Only unconditional failure */
}
diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c
index 9cf68280..9858307e 100644
--- a/modules/pam_time/pam_time.c
+++ b/modules/pam_time/pam_time.c
@@ -8,7 +8,7 @@
* shadow-960129)
*/
-const static char rcsid[] =
+static const char rcsid[] =
"$Id$;\n"
"\t\tVersion 0.22 for Linux-PAM\n"
"Copyright (C) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n";
@@ -127,6 +127,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
i = read(fd, *to + *buf, PAM_TIME_BUFLEN - *to);
if (i < 0) {
_log_err("error reading " PAM_TIME_CONF);
+ close(fd);
return -1;
} else if (!i) {
close(fd);
@@ -166,6 +167,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
} else {
_log_err("internal error in " __FILE__
" at line %d", __LINE__ );
+ close(fd);
return -1;
}
break;
diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c
index 67497e06..a0c1da81 100644
--- a/modules/pam_unix/pam_unix_auth.c
+++ b/modules/pam_unix/pam_unix_auth.c
@@ -15,13 +15,13 @@
* 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
@@ -88,7 +88,8 @@ do { \
*ret_data = retval; \
pam_set_data(pamh, "unix_setcred_return", \
(void *) ret_data, setcred_free); \
- } \
+ } else if (ret_data) \
+ free (ret_data); \
D(("done. [%s]", pam_strerror(pamh, retval))); \
return retval; \
} while (0)
@@ -183,7 +184,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
}
-/*
+/*
* The only thing _pam_set_credentials_unix() does is initialization of
* UNIX group IDs.
*
@@ -203,7 +204,7 @@ PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags
retval = PAM_SUCCESS;
D(("recovering return code from auth call"));
- /* We will only find something here if UNIX_LIKE_AUTH is set --
+ /* We will only find something here if UNIX_LIKE_AUTH is set --
don't worry about an explicit check of argv. */
pam_get_data(pamh, "unix_setcred_return", (const void **) &pretval);
if(pretval) {
diff --git a/modules/pam_wheel/pam_wheel.c b/modules/pam_wheel/pam_wheel.c
index 2ac1eecb..9545231b 100644
--- a/modules/pam_wheel/pam_wheel.c
+++ b/modules/pam_wheel/pam_wheel.c
@@ -112,7 +112,7 @@ static int perform_check(pam_handle_t *pamh, int flags, int ctrl,
{
const char *username = NULL;
const char *fromsu;
- struct passwd *pwd, *tpwd;
+ struct passwd *pwd, *tpwd = NULL;
struct group *grp;
int retval = PAM_AUTH_ERR;
diff --git a/modules/pammodutil/Makefile b/modules/pammodutil/Makefile
index b4868528..c1f1b9a7 100644
--- a/modules/pammodutil/Makefile
+++ b/modules/pammodutil/Makefile
@@ -19,7 +19,7 @@ CFLAGS += $(PIC) $(STATIC) $(MOREFLAGS) \
# all the object files we care about
LIBOBJECTS = modutil_cleanup.o modutil_getpwnam.o modutil_getpwuid.o \
- modutil_getlogin.o
+ modutil_getlogin.o modutil_ioloop.o
# static library name
LIBSTATIC = $(LIBNAME).a
diff --git a/modules/pammodutil/include/security/_pam_modutil.h b/modules/pammodutil/include/security/_pam_modutil.h
index 5e063651..5b95e279 100644
--- a/modules/pammodutil/include/security/_pam_modutil.h
+++ b/modules/pammodutil/include/security/_pam_modutil.h
@@ -32,4 +32,8 @@ extern void _pammodutil_cleanup(pam_handle_t *pamh, void *data,
extern const char *_pammodutil_getlogin(pam_handle_t *pamh);
+extern int _pammodutil_read(int fd, char *buffer, int count);
+
+extern int _pammodutil_write(int fd, const char *buffer, int count);
+
#endif /* _PAM_MODUTIL_H */
diff --git a/modules/pammodutil/modutil_ioloop.c b/modules/pammodutil/modutil_ioloop.c
new file mode 100644
index 00000000..4176b658
--- /dev/null
+++ b/modules/pammodutil/modutil_ioloop.c
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * These functions provides common methods for ensure a complete read or
+ * write occurs. It handles EINTR and partial read/write returns.
+ */
+
+#include <unistd.h>
+#include <errno.h>
+
+int _pammodutil_read(int fd, char *buffer, int count)
+{
+ int block, offset = 0;
+
+ while (count > 0) {
+ block = read(fd, &buffer[offset], count);
+
+ if (block < 0) {
+ if (errno == EINTR) continue;
+ return block;
+ }
+ if (block == 0) return offset;
+
+ offset += block;
+ count -= block;
+ }
+
+ return offset;
+}
+
+int _pammodutil_write(int fd, const char *buffer, int count)
+{
+ int block, offset = 0;
+
+ while (count > 0) {
+ block = write(fd, &buffer[offset], count);
+
+ if (block < 0) {
+ if (errno == EINTR) continue;
+ return block;
+ }
+ if (block == 0) return offset;
+
+ offset += block;
+ count -= block;
+ }
+
+ return offset;
+}
+