diff options
author | Arthur de Jong <arthur@arthurdejong.org> | 2010-05-10 22:59:52 +0200 |
---|---|---|
committer | Arthur de Jong <arthur@arthurdejong.org> | 2010-05-10 22:59:52 +0200 |
commit | 7061d2c2f7a376721f196f7f88253b3a0428e980 (patch) | |
tree | 6e9826062ac2e2756d537cc62ed4adb0a1f387f6 /compat | |
parent | a672d0d688d3ee0e66c0f15287d9f9fcc32d45bf (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
Diffstat (limited to 'compat')
-rw-r--r-- | compat/Makefile.am | 2 | ||||
-rw-r--r-- | compat/pam_compat.h | 18 | ||||
-rw-r--r-- | compat/pam_get_authtok.c | 37 | ||||
-rw-r--r-- | compat/pam_prompt.c | 72 |
4 files changed, 92 insertions, 37 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; +} |