> Is that the exact format of the code? also, what is before and after? Pretty much is yes. The annoying thing is that it works without a problem in linux, but crashes before even entering the conversation function (as far as I can tell) in solaris. One thing I did notice is that in solaris I had to define the conversation function as: int change_conv(int, struct pam_message **, struct pam_response **, void *); instead of: int change_conv(int, const struct pam_message **, struct pam_response **, void *); as g++ wouldn't compile it with the second because of the const modifier. Could this contribute? Here are all the particulars (without pasting the whole file - if having all the source would be helpful I can email that to you as its quite large) - putting just my conversation stuff and the code that calls it (all included below) into a program running it behaves the same, so I suspect something I have missed, rather than something odd elsewhere in the code. I appreciate the help! Nate === code === // Global data (as passing data in solaris via the pam_conv structure doesnt work): char *gl_username, *gl_password; char *old_pass, *new_pass; int gl_authenticated; // Definition of conversation function: int change_conv(int, const struct pam_message **, struct pam_response **, void *); // pam_conv structure: static struct pam_conv changeconv = { change_conv, NULL }; // The actual conversation function: int change_conv(int num_msg, struct pam_message **msg, struct pam_response **response, void *appdata_ptr) { struct pam_response *reply_with = NULL; int num_replies; char buffer[80]; if( num_msg <= 0 ) return PAM_CONV_ERR; reply_with = (struct pam_response *)calloc(num_msg, sizeof(struct pam_response)); if( reply_with == NULL ) return PAM_SYSTEM_ERR; memset(buffer,'\0',sizeof(buffer)); for( num_replies = 0; num_replies < num_msg; num_replies++ ) { if( msg[num_replies]->msg_style == PAM_PROMPT_ECHO_OFF ) { reply_with[num_replies].resp_retcode = PAM_SUCCESS; reply_with[num_replies].resp = strdup(new_pass); } else if( msg[num_replies]->msg_style == PAM_PROMPT_ECHO_ON ) { reply_with[num_replies].resp_retcode = PAM_SUCCESS; reply_with[num_replies].resp = strdup(gl_username); } else { free(reply_with); return PAM_CONV_ERR; } } *response = reply_with; return PAM_SUCCESS; } // My code functions as a server using OpenSSL - when a client connects and says they want to // change a password, the username, old password, and new password are all given. I then use // a different conversation function and authenticate the user - being sure to call pam_start // and pam_end if( (ret = pam_start("login", NULL, &authconv, &pamh)) == PAM_SUCCESS ) if( (ret = pam_authenticate(pamh, 0)) == PAM_SUCCESS ) if( (ret = pam_acct_mgmt(pamh, 0)) == PAM_SUCCESS ) authenticated = 1; pam_end(pamh,ret); // As long as that succeeds, then I call the following to change the password with the code // given above: if( (ret = pam_start("passwd", NULL, &changeconv, &pamh)) == PAM_SUCCESS ) if( (ret = pam_chauthtok(pamh, PAM_SILENT)) == PAM_SUCCESS ) changed = 1; pam_end(pamh,ret); ==== end code ==== _______________________________________________ Pam-list@redhat.com https://listman.redhat.com/mailman/listinfo/pam-list