This example won't really work, but it should be clear enough. If you need any comments, ask me. struct myOwnData { const char *password; const char *username; }; int myConv(int numMsg, const struct pam_message **msg, struct pam_response **response, void *appdataPtr) { struct pam_response *reply = NULL; int replies; struct myOwnData *data = (struct myOwnData *)appdataPtr; if (data == NULL) return PAM_SYSTEM_ERR; if (numMsg <= 0) return PAM_CONV_ERR; reply = (struct pam_response *)calloc(numMsg, sizeof(struct pam_response)); if (reply == NULL) return PAM_SYSTEM_ERR; for (replies = 0; replies < numMsg; replies++) { switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_OFF: /* ? password */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = strdup(data->password); break; case PAM_PROMPT_ECHO_ON: /* ? username */ reply[replies].resp_retcode = PAM_SUCCESS; reply[replies].resp = strdup(data->username); break; default: /* what does pam want? */ free(reply); return PAM_CONV_ERR; } } *resp = reply; return PAM_SUCCESS; } struct pam_conv pamConv = { myConv, NULL }; int authenticate(const char *username, const char *password, const char *service) { struct myOwnData myData; pam_handle_t *ph = NULL; int retval; myData.username = username; myData.password = password; pamConv.appdata_ptr = &myData; pam_start(service, username, &pamConv, &ph); pam_authenticate(ph, 0); retval = pam_acct_mgmt(ph, 0); pam_end(ph, retval); return retval; } With regards Ondrej Svetlik