Greetings.
I'm having a problem using PAM on Sparc Solaris 2.6. Specifically, the
appdata_ptr in the conv structure which I pass to pam_start() isn't
getting passed on to the conv function when called. Is there a known
problem with this? Note that I do have the two recommended PAM patches
applied.
I've attached a short program below which demonstrates this behaviour.
Note that it works properly on x86/Linux. On Solaris, the warning about
appdata_ptr being null is always displayed.
Am I missing something, or is this a bug in PAM on Solaris 2.6?
Thanks.
//Mark
--
Mark G. Adams
Software Developer
LivePage Corporation
Waterloo, Ontario, Canada
-----------------
#include <stdio.h>
#include <stdlib.h>
#include <security/pam_appl.h>
int livepage_conv(int num_msg,
const struct pam_message **msg,
struct pam_response **resp,
void *appdata_ptr) {
struct pam_response *p = NULL;
int i,j,ret = PAM_CONV_ERR;
if( !appdata_ptr ) {
printf( "Warning: appdata_ptr is NULL.\n" );
}
/* Allocate the array to be returned and zero it */
p = (struct pam_response *)malloc( sizeof( struct pam_response ) *
num_msg );
memset( p, '\0', sizeof( struct pam_response ) * num_msg );
/* Cycle through each message (should only just get 1, but let's be
thorough */
for( i = 0; i < num_msg; i++ ) {
switch( msg[i]->msg_style ) {
case PAM_PROMPT_ECHO_OFF:
case PAM_PROMPT_ECHO_ON:
if( !appdata_ptr ) {
appdata_ptr = "";
}
p[i].resp = (char *)malloc( sizeof( char ) *
( strlen( (char *)appdata_ptr ) + 1 ) );
/* Just in case */
if( p[i].resp == NULL ) {
for( j = 0; j < i; j++ ) {
if( p[j].resp != NULL ) {
free( p[j].resp );
}
}
goto done;
}
strcpy( p[i].resp, (char *)appdata_ptr );
break;
default:
/* We simply ignore text */
break;
}
}
*resp = p;
ret = PAM_SUCCESS;
done:
if( (ret != PAM_SUCCESS ) && ( p != NULL ) ) {
free( p );
}
return ret;
int main( int argc, char *argv[] ) {Quote:}
pam_handle_t *pamh = NULL;
struct pam_conv conv;
int retval;
if( ( argc < 2 ) || ( argc > 3 ) ) {
printf( "Syntax: pamtest <user> [<password>]\n" );
return 1;
}
conv.conv = livepage_conv;
if( argc == 3 ) {
conv.appdata_ptr = (void *)argv[ 2 ];
} else {
conv.appdata_ptr = NULL;
}
if( ( retval = pam_start( "myservice", argv[ 1 ], &conv, &pamh ) )
!=
PAM_SUCCESS ) {
printf( "Pam error: %s\n", pam_strerror( NULL, retval ) );
return 1;
}
if( ( retval = pam_authenticate( pamh, 0 ) ) != PAM_SUCCESS ) {
printf( "Pam error: %s\n", pam_strerror( pamh, retval ) );
pam_end( pamh, retval );
return 1;
}
if( ( retval = pam_acct_mgmt( pamh, 0 ) ) != PAM_SUCCESS ) {
printf( "Pam error: %s\n", pam_strerror( pamh, retval ) );
pam_end( pamh, retval );
return 1;
}
printf( "Authorized.\n" );
pam_end( pamh, retval);
return 0;
Quote:}