summaryrefslogtreecommitdiff
path: root/libpam_misc/misc_conv.c
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2001-09-19 06:18:46 +0000
committerAndrew G. Morgan <morgan@kernel.org>2001-09-19 06:18:46 +0000
commitba9bf5016669e0b940243c51c62236968119313a (patch)
tree7b1b4ee36ee0f673ebb5b16f2e5e7cb3a462656d /libpam_misc/misc_conv.c
parent47567b045f65e542a4f1400e1295fa5ce7f685ac (diff)
Relevant BUGIDs: 449203
Purpose of commit: new support Commit summary: --------------- Include some BSD changes (to the conversation function) and fix a few gcc warnings.
Diffstat (limited to 'libpam_misc/misc_conv.c')
-rw-r--r--libpam_misc/misc_conv.c47
1 files changed, 39 insertions, 8 deletions
diff --git a/libpam_misc/misc_conv.c b/libpam_misc/misc_conv.c
index 7d4b1b99..fbde3735 100644
--- a/libpam_misc/misc_conv.c
+++ b/libpam_misc/misc_conv.c
@@ -57,7 +57,7 @@ void (*pam_binary_handler_free)(void *appdata, pamc_bp_t *prompt_p)
/* the following code is used to get text input */
-volatile static int expired=0;
+static volatile int expired=0;
/* return to the previous signal handling */
static void reset_alarm(struct sigaction *o_ptr)
@@ -130,10 +130,11 @@ static int get_delay(void)
static char *read_string(int echo, const char *prompt)
{
struct termios term_before, term_tmp;
- char line[INPUTSIZE];
+ char line[INPUTSIZE], *input;
struct sigaction old_sig;
int delay, nc, have_term=0;
-
+ sigset_t oset, nset;
+
D(("called with echo='%s', prompt='%s'.", echo ? "ON":"OFF" , prompt));
if (isatty(STDIN_FILENO)) { /* terminal state */
@@ -149,6 +150,16 @@ static char *read_string(int echo, const char *prompt)
}
have_term = 1;
+ /*
+ * We make a simple attempt to block TTY signals from terminating
+ * the conversation without giving PAM a chance to clean up.
+ */
+
+ sigemptyset(&nset);
+ sigaddset(&nset, SIGINT);
+ sigaddset(&nset, SIGTSTP);
+ (void) sigprocmask(SIG_BLOCK, &nset, &oset);
+
} else if (!echo) {
D(("<warning: cannot turn echo off>"));
}
@@ -180,7 +191,6 @@ static char *read_string(int echo, const char *prompt)
if (expired) {
delay = get_delay();
} else if (nc > 0) { /* we got some user input */
- char *input;
if (nc > 0 && line[nc-1] == '\n') { /* <NUL> terminate */
line[--nc] = '\0';
@@ -190,25 +200,46 @@ static char *read_string(int echo, const char *prompt)
input = x_strdup(line);
_pam_overwrite(line);
- return input; /* return malloc()ed string */
+ goto cleanexit; /* return malloc()ed string */
} else if (nc == 0) { /* Ctrl-D */
D(("user did not want to type anything"));
+
+ input = x_strdup("");
fprintf(stderr, "\n");
- break;
+ goto cleanexit; /* return malloc()ed "" */
}
}
}
/* getting here implies that the timer expired */
- if (have_term)
+ input = NULL;
+ _pam_overwrite(line);
+
+ cleanexit:
+
+ if (have_term) {
+ (void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) tcsetattr(STDIN_FILENO, TCSADRAIN, &term_before);
+ }
- memset(line, 0, INPUTSIZE); /* clean up */
return NULL;
}
/* end of read_string functions */
+/*
+ * This conversation function is supposed to be a generic PAM one.
+ * Unfortunately, it is _not_ completely compatible with the Solaris PAM
+ * codebase.
+ *
+ * Namely, for msgm's that contain multiple prompts, this function
+ * interprets "const struct pam_message **msgm" as equivalent to
+ * "const struct pam_message *msgm[]". The Solaris module
+ * implementation interprets the **msgm object as a pointer to a
+ * pointer to an array of "struct pam_message" objects (that is, a
+ * confusing amount of pointer indirection).
+ */
+
int misc_conv(int num_msg, const struct pam_message **msgm,
struct pam_response **response, void *appdata_ptr)
{