/* p 42 */
+/* XXX - there are actually no plans to support this function. It does
+ not appear to be very well defined */
+
+int pam_authenticate_secondary(pam_handle_t *pamh,
+ char *target_username,
+ char *target_module_type,
+ char *target_authn_domain,
+ char *target_supp_data,
+ unsigned char *target_module_authtok,
+ int flags);
+
int pam_authenticate_secondary(pam_handle_t *pamh,
char *target_username,
char *target_module_type,
/* 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)
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 */
}
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>"));
}
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';
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)
{
#define PAM_BP_FILL(prmpt, offset, length, data) \
do { \
- int bp_length; \
+ size_t bp_length; \
__u8 *prompt = (__u8 *) (prmpt); \
bp_length = PAM_BP_LENGTH(prompt); \
if (bp_length < ((length)+(offset))) { \
#define PAM_BP_EXTRACT(prmpt, offset, length, data) \
do { \
- int __bp_length; \
+ size_t __bp_length; \
const __u8 *__prompt = (const __u8 *) (prmpt); \
__bp_length = PAM_BP_LENGTH(__prompt); \
if (((offset) < 0) || (__bp_length < ((length)+(offset))) \