diff --git a/ChangeLog b/ChangeLog index 74298752..4f51ed07 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2009-04-28 Nicolas François + + * lib/prototypes.h: Replace #if by #ifdef + * lib/prototypes.h, libmisc/non_interactive_pam_conv.c: Added + non_interactive_pam_conv() and non_interactive_password. + 2009-04-28 Nicolas François * libmisc/utmp.c, src/userdel.c, src/logoutd.c: Replace #if by #ifdef diff --git a/lib/prototypes.h b/lib/prototypes.h index 1aeabd3b..dfeedfec 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -43,7 +43,7 @@ #define _PROTOTYPES_H #include -#if USE_UTMPX +#ifdef USE_UTMPX #include #else #include @@ -238,6 +238,10 @@ extern void motd (void); /* myname.c */ extern /*@null@*/struct passwd *get_my_pwent (void); +/* non_interactive_pam_conv.c */ +/*@null@*/ /*@only@*/extern char *non_interactive_password; +extern struct pam_conv non_interactive_pam_conv; + /* obscure.c */ #ifndef USE_PAM extern int obscure (const char *, const char *, const struct passwd *); diff --git a/libmisc/non_interactive_pam_conv.c b/libmisc/non_interactive_pam_conv.c new file mode 100644 index 00000000..282300b2 --- /dev/null +++ b/libmisc/non_interactive_pam_conv.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009, Nicolas François + * All rights reserved. + * + * 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, this list of conditions and the following disclaimer. + * 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 copyright holders or contributors may not be used to + * endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``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 COPYRIGHT + * HOLDERS OR CONTRIBUTORS 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 + +#ident "$Id:$" + +#include +#include +#include +#include +#include +#include "prototypes.h" + +/*@null@*/ /*@only@*/char *non_interactive_password = NULL; + + +static int ni_conv (int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) { + struct pam_response *responses; + int count; +fputs ("ni_conv\n", stderr); + + assert (NULL != non_interactive_password); + + if (num_msg <= 0) { + return PAM_CONV_ERR; + } + + responses = (struct pam_response *) calloc (num_msg, + sizeof (*responses)); + if (NULL == responses) { + return PAM_CONV_ERR; + } + + for (count=0; count < num_msg; count++) { + responses[count].resp_retcode = 0; + + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: +fputs ("PAM_PROMPT_ECHO_ON\n", stderr); + fprintf (stderr, + _("%s: PAM modules requesting echoing are not supported.\n"), + Prog); + goto failed_conversation; + case PAM_PROMPT_ECHO_OFF: +fputs ("PAM_PROMPT_ECHO_OFF\n", stderr); + responses[count].resp = strdup (non_interactive_password); + if (NULL == responses[count].resp) { + goto failed_conversation; + } + break; + case PAM_ERROR_MSG: + if ( (NULL == msg[count]->msg) + || (fprintf (stderr, "%s\n", msg[count]->msg) <0)) { + goto failed_conversation; + } + responses[count].resp = NULL; + break; + case PAM_TEXT_INFO: + if ( (NULL == msg[count]->msg) + || (fprintf (stdout, "%s\n", msg[count]->msg) <0)) { + goto failed_conversation; + } + responses[count].resp = NULL; + break; + default: + (void) fprintf (stderr, + _("%s: conversation type %d not supported.\n"), + Prog, msg[count]->msg_style); + goto failed_conversation; + } + } + + *resp = responses; + + return PAM_SUCCESS; + +failed_conversation: + for (count=0; count < num_msg; count++) { + if (NULL != responses[count].resp) { + memset (responses[count].resp, 0, + strlen (responses[count].resp)); + free (responses[count].resp); + responses[count].resp = NULL; + } + } + + free (responses); + *resp = NULL; + + return PAM_CONV_ERR; +} + +struct pam_conv non_interactive_pam_conv = { + ni_conv, + NULL +}; +