summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2010-05-10 20:59:52 +0000
committerArthur de Jong <arthur@arthurdejong.org>2010-05-10 20:59:52 +0000
commit7061d2c2f7a376721f196f7f88253b3a0428e980 (patch)
tree6e9826062ac2e2756d537cc62ed4adb0a1f387f6
parenta672d0d688d3ee0e66c0f15287d9f9fcc32d45bf (diff)
replace my_pam_warn() with pam_info() and pam_error() and provide replacement for pam_prompt() also using it in our pam_get_authtok() replacement
git-svn-id: http://arthurdejong.org/svn/nss-pam-ldapd/nss-pam-ldapd@1098 ef36b2f9-881f-0410-afb5-c4e39611909c
-rw-r--r--compat/Makefile.am2
-rw-r--r--compat/pam_compat.h18
-rw-r--r--compat/pam_get_authtok.c37
-rw-r--r--compat/pam_prompt.c72
-rw-r--r--configure.ac4
-rw-r--r--pam/pam.c57
6 files changed, 106 insertions, 84 deletions
diff --git a/compat/Makefile.am b/compat/Makefile.am
index dbe2144..06ac51b 100644
--- a/compat/Makefile.am
+++ b/compat/Makefile.am
@@ -26,7 +26,7 @@ EXTRA_DIST = getopt_long.c getopt_long.h \
daemon.c daemon.h \
ether.c ether.h \
ldap_compat.h pagectrl.c ldap_passwd_s.c ldap_initialize.c \
- pam_compat.h pam_get_authtok.c
+ pam_compat.h pam_get_authtok.c pam_prompt.c
libcompat_a_SOURCES = getpeercred.c getpeercred.h
libcompat_a_LIBADD = @LIBOBJS@
diff --git a/compat/pam_compat.h b/compat/pam_compat.h
index c453061..f3607af 100644
--- a/compat/pam_compat.h
+++ b/compat/pam_compat.h
@@ -40,7 +40,23 @@
/* define our own replacement pam_get_authtok() if it wasn't found */
#ifndef HAVE_PAM_GET_AUTHTOK
int pam_get_authtok(pam_handle_t *pamh,int item,const char **authtok,const char *prompt);
-#endif /* HAVE_PAM_GET_AUTHTOK */
+#endif /* not HAVE_PAM_GET_AUTHTOK */
+
+/* replace pam_prompt() if needed */
+#ifndef HAVE_PAM_PROMPT
+int pam_prompt(pam_handle_t *pamh,int style,char **response,const char *format,...)
+ LIKE_PRINTF(4,5);
+#endif /* not HAVE_PAM_PROMPT */
+
+/* provide pam_info() if needed */
+#ifndef pam_info
+#define pam_info(pamh, fmt...) pam_prompt(pamh,PAM_TEXT_INFO,NULL,__VA_ARGS__)
+#endif /* not pam_info */
+
+/* provide pam_error() if needed */
+#ifndef pam_error
+#define pam_error(pamh, fmt...) pam_prompt(pamh,PAM_ERROR_MSG,NULL,__VA_ARGS__)
+#endif /* not pam_error */
/* fall back to using getpwnam() if pam_modutil_getpwnam() isn't defined */
#ifndef HAVE_PAM_MODUTIL_GETGWNAM
diff --git a/compat/pam_get_authtok.c b/compat/pam_get_authtok.c
index c471d34..225ab81 100644
--- a/compat/pam_get_authtok.c
+++ b/compat/pam_get_authtok.c
@@ -32,41 +32,12 @@
#include "compat/attrs.h"
#include "compat/pam_compat.h"
-static int prompt_passwd(struct pam_conv *conv,const char *prompt,
- char **passwd)
-{
- struct pam_message msg,*msgs[1];
- struct pam_response *resp;
- int rc;
- /* provide fallback */
- *passwd=NULL;
- /* set up prompt */
- msg.msg_style=PAM_PROMPT_ECHO_OFF;
- msg.msg=prompt;
- msgs[0]=&msg;
- resp=NULL;
- rc=conv->conv(1,(const struct pam_message **)msgs,&resp,conv->appdata_ptr);
- if (rc!=PAM_SUCCESS)
- return rc;
- else if (resp==NULL)
- return PAM_CONV_ERR;
- else if (resp[0].resp==NULL)
- {
- free(resp);
- return PAM_CONV_ERR;
- }
- *passwd=resp[0].resp;
- resp[0].resp=NULL;
- free(resp);
- return PAM_SUCCESS;
-}
int pam_get_authtok(pam_handle_t *pamh,int item,const char **authtok,const char *prompt)
{
int rc;
char *passwd=NULL,*retype_passwd=NULL;
const void *oldauthtok;
- struct pam_conv *conv;
char retype_prompt[80];
/* first try to see if the value is already on the stack */
*authtok=NULL;
@@ -89,18 +60,14 @@ int pam_get_authtok(pam_handle_t *pamh,int item,const char **authtok,const char
else
prompt=(prompt!=NULL)?prompt:"Password: ";
}
- /* get PAM_CONV */
- rc=pam_get_item(pamh,PAM_CONV,(const void **)&conv);
- if (rc!=PAM_SUCCESS)
- return rc;
/* prepare prompt and get password */
- rc=prompt_passwd(conv,prompt,&passwd);
+ rc=pam_prompt(pamh,PAM_PROMPT_ECHO_OFF,&passwd,"%s",prompt);
if (rc!=PAM_SUCCESS)
return rc;
/* if a second prompt should be presented, do it */
if (*retype_prompt)
{
- rc=prompt_passwd(conv,retype_prompt,&retype_passwd);
+ rc=pam_prompt(pamh,PAM_PROMPT_ECHO_OFF,&retype_passwd,"%s",retype_prompt);
/* check passwords */
if ((rc==PAM_SUCCESS)&&(strcmp(retype_passwd,passwd)!=0))
rc=PAM_AUTHTOK_RECOVERY_ERR;
diff --git a/compat/pam_prompt.c b/compat/pam_prompt.c
new file mode 100644
index 0000000..6e1b779
--- /dev/null
+++ b/compat/pam_prompt.c
@@ -0,0 +1,72 @@
+/*
+ pam_prompt.c - replacement function for pam_prompt()
+
+ Copyright (C) 2010 Arthur de Jong
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "compat/attrs.h"
+#include "compat/pam_compat.h"
+
+int pam_prompt(pam_handle_t *pamh,int style,char **response,const char *format,...)
+{
+ int rc;
+ struct pam_conv *aconv;
+ char buffer[200];
+ va_list ap;
+ struct pam_message msg, *pmsg;
+ struct pam_response *resp;
+ /* the the conversion function */
+ rc=pam_get_item(pamh,PAM_CONV,(const void **)&aconv);
+ if (rc!=PAM_SUCCESS)
+ return rc;
+ /* make the message string */
+ va_start(ap,format);
+ vsnprintf(buffer,sizeof(buffer),format,ap);
+ buffer[sizeof(buffer)-1]='\0';
+ va_end(ap);
+ /* build the message */
+ msg.msg_style=style;
+ msg.msg=buffer;
+ pmsg=&msg;
+ resp=NULL;
+ rc=aconv->conv(1,(const struct pam_message **)&pmsg,&resp,aconv->appdata_ptr);
+ if (rc!=PAM_SUCCESS)
+ return rc;
+ /* assign response if it is set */
+ if (response!=NULL)
+ {
+ if (resp==NULL)
+ return PAM_CONV_ERR;
+ if (resp[0].resp==NULL)
+ {
+ free(resp);
+ return PAM_CONV_ERR;
+ }
+ *response=resp[0].resp;
+ }
+ else
+ free(resp[0].resp);
+ free(resp);
+ return PAM_SUCCESS;
+}
diff --git a/configure.ac b/configure.ac
index c02d7df..cf238b1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -308,8 +308,8 @@ then
save_LIBS="$LIBS"
# find pam library
AC_SEARCH_LIBS(pam_get_data,pam,,AC_MSG_ERROR(no PAM library available))
- # replace the pam_get_authtok() function if it's unavailable
- AC_REPLACE_FUNCS(pam_get_authtok)
+ # replace some PAM functions if they are unavailable
+ AC_REPLACE_FUNCS(pam_get_authtok pam_prompt)
AC_CHECK_FUNCS(pam_modutil_getpwnam)
# restore CFLAGS and LIBS
CFLAGS="$save_CFLAGS"
diff --git a/pam/pam.c b/pam/pam.c
index b09eb24..7fc8d78 100644
--- a/pam/pam.c
+++ b/pam/pam.c
@@ -351,26 +351,6 @@ int pam_sm_setcred(pam_handle_t UNUSED(*pamh),int UNUSED(flags),
return PAM_SUCCESS;
}
-static int my_pam_warn(
- struct pam_conv *aconv, const char *message, int style, int no_warn)
-{
- struct pam_message msg, *pmsg;
- struct pam_response *resp;
-
- if (no_warn)
- return PAM_SUCCESS;
-
- pmsg=&msg;
-
- msg.msg_style=style;
- msg.msg=(char *)message;
- resp=NULL;
-
- return aconv->conv(1,
- (const struct pam_message **) &pmsg,
- &resp, aconv->appdata_ptr);
-}
-
/* perform an authorisation call over nslcd */
static int nslcd_request_authz(pld_ctx *ctx,const char *username,
const char *service,const char *ruser,
@@ -397,7 +377,6 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv)
const char *username,*svc,*ruser,*rhost,*tty;
int no_warn=0, ignore_flags=0;
int i;
- struct pam_conv *appconv;
pld_ctx *ctx=NULL, ctx2;
uid_t minimum_uid=0;
struct passwd *pwent;
@@ -425,9 +404,6 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv)
if (flags&PAM_SILENT)
no_warn=1;
- rc=pam_get_item(pamh,PAM_CONV,(const void **)&appconv);
- if (rc!=PAM_SUCCESS)
- return rc;
/* get user name */
rc=pam_get_user(pamh,(const char **)&username,NULL);
if (rc!=PAM_SUCCESS)
@@ -472,18 +448,21 @@ int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc,const char **argv)
if (rc!=PAM_SUCCESS)
{
if (rc!=PAM_IGNORE)
- my_pam_warn(appconv,"LDAP authorization failed",PAM_ERROR_MSG,no_warn);
+ if (!no_warn)
+ pam_error(pamh,"LDAP authorization failed");
}
else
{
rc=ctx2.authz;
if (ctx2.authzmsg && ctx2.authzmsg[0])
- my_pam_warn(appconv,ctx2.authzmsg,PAM_TEXT_INFO,no_warn);
+ if (!no_warn)
+ pam_info(pamh,"%s",ctx2.authzmsg);
if (ctx2.authz==PAM_SUCCESS)
{
rc=ctx->authz;
if (ctx->authzmsg && ctx->authzmsg[0])
- my_pam_warn(appconv,ctx->authzmsg,PAM_TEXT_INFO,no_warn);
+ if (!no_warn)
+ pam_info(pamh,"%s",ctx->authzmsg);
}
}
@@ -583,15 +562,11 @@ int pam_sm_open_session(
pam_handle_t *pamh, int flags, int argc, const char **argv)
{
int rc, no_warn=0;
- struct pam_conv *appconv;
-
- rc=pam_get_item(pamh,PAM_CONV,(const void **)&appconv);
- if (rc!=PAM_SUCCESS)
- return rc;
rc=pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_O,&no_warn);
if ((rc!=PAM_SUCCESS)&&(rc!=PAM_IGNORE))
- my_pam_warn(appconv,"LDAP open_session failed",PAM_ERROR_MSG,no_warn);
+ if (!no_warn)
+ pam_error(pamh,"LDAP open_session failed");
return rc;
}
@@ -599,15 +574,11 @@ int pam_sm_close_session(
pam_handle_t *pamh, int flags, int argc, const char **argv)
{
int rc, no_warn=0;
- struct pam_conv *appconv;
-
- rc=pam_get_item(pamh,PAM_CONV,(const void **)&appconv);
- if (rc!=PAM_SUCCESS)
- return rc;
rc=pam_sm_session(pamh,flags,argc,argv,NSLCD_ACTION_PAM_SESS_C,&no_warn);
if ((rc!=PAM_SUCCESS)&&(rc!=PAM_IGNORE))
- my_pam_warn(appconv,"LDAP close_session failed",PAM_ERROR_MSG,no_warn);
+ if (!no_warn)
+ pam_error(pamh,"LDAP close_session failed");
return rc;
}
@@ -669,7 +640,6 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
const char *newpassword=NULL;
int first_pass=0, no_warn=0, ignore_flags=0;
int i;
- struct pam_conv *appconv;
pld_ctx *ctx=NULL;
uid_t minimum_uid=0;
struct passwd *pwent;
@@ -699,9 +669,6 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
if (flags&PAM_SILENT)
no_warn=1;
- rc=pam_get_item(pamh,PAM_CONV,(const void **)&appconv);
- if (rc!=PAM_SUCCESS)
- return rc;
/* get user name */
rc=pam_get_user(pamh,(const char **)&username,NULL);
if (rc!=PAM_SUCCESS)
@@ -778,8 +745,8 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc,const char **argv)
rc=PAM_IGNORE;
else if ((rc==PAM_USER_UNKNOWN)&&(ignore_flags&IGNORE_UNKNOWN))
rc=PAM_IGNORE;
- else
- my_pam_warn(appconv,ctx->authzmsg,PAM_ERROR_MSG,no_warn);
+ else if (!no_warn)
+ pam_error(pamh,"%s",ctx->authzmsg);
return rc;
}