/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #include #include #include #include #include #include static int misc_conv(int num_msg, struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int n = 0; char *userPassword; struct pam_response *r; struct pam_message *m = *msg; int pam_status = PAM_SUCCESS; *resp = (struct pam_response *)calloc(num_msg, sizeof (struct pam_response)); if (resp == NULL) return (PAM_BUF_ERR); r = *resp; for (n = 0; n < num_msg; n++) { switch (m->msg_style) { case PAM_PROMPT_ECHO_OFF: userPassword = (char *)getpassphrase(m->msg); r->resp = (char *)strdup(userPassword); if (r->resp == NULL) { return (PAM_BUF_ERR); } break; case PAM_PROMPT_ECHO_ON: printf("%s", m->msg); r->resp = (char *)malloc(PAM_MAX_RESP_SIZE); fgets(r->resp, PAM_MAX_RESP_SIZE - 1, stdin); if (strlen(r->resp) == 1) { free(r->resp); r->resp = NULL; pam_status = PAM_IGNORE; } else { r->resp[strlen(r->resp) - 1] = '\0'; m++; r++; } break; case PAM_ERROR_MSG: if (m->msg != NULL) { printf("ECHO_ERROR: %s\n", m->msg); } else { printf("ECHO_ERROR: NULL MSG\n"); } break; case PAM_TEXT_INFO: if (m->msg != NULL) { printf("TEXT_INFO: %s\n", m->msg); } else { printf("TEXT_INFO: NULL MSG\n"); } break; default: if (m->msg != NULL) { printf("default: %s\n", m->msg); } else { printf("default NULL MSG\n"); } break; } m++; } return (pam_status); } void main(int argc, char *argv[]) { int ret = -1; struct pam_conv pconv = {misc_conv, NULL}; pam_handle_t *pamh = NULL; char *service = NULL; char *user = NULL; char c; while ((c = getopt(argc, argv, "s:u:")) != EOF) { switch (c) { case 's': service = strdup(optarg); break; case 'u': user = strdup(optarg); break; default: fprintf(stderr, "Invalid argument\n"); exit(1); } } if (service == NULL) { service = strdup("testapp"); } if ((ret = pam_start(service, user, &pconv, &pamh)) != PAM_SUCCESS) { printf("%s\n", pam_strerror(pamh, ret)); exit(1); } pam_set_item(pamh, PAM_TTY, ttyname(1)); fprintf(stderr, "Authenticating...\n"); ret = pam_authenticate(pamh, 0); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_authenticate failed: %s\n", pam_strerror(pamh, ret)); exit(1); } fprintf(stderr, "Account management...\n"); ret = pam_acct_mgmt(pamh, 0); if (ret == PAM_NEW_AUTHTOK_REQD) { fprintf(stdout, "Expired password needs changing."); ret = pam_chauthtok(pamh, 0); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_chauthtok failed: %s\n", pam_strerror(pamh, ret)); exit(1); } } else if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_acct_mgmt failed: %s\n", pam_strerror(pamh, ret)); exit(1); } fprintf(stderr, "Establishing creds...\n"); ret = pam_setcred(pamh, PAM_ESTABLISH_CRED); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_setcred PAM_ESTALISH_CRED failed: %s\n", pam_strerror(pamh, ret)); } fprintf(stderr, "Opening session...\n"); ret = pam_open_session(pamh, 0); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_open_session failed: %s\n", pam_strerror(pamh, ret)); } /* * Pretend some time has passed, a refresh would normally be * done after a re-authenticate, eg in a screen saver. */ fprintf(stderr, "Refresh creds...\n"); ret = pam_setcred(pamh, PAM_REFRESH_CRED); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_setcred PAM_REFRESH_CRED failed: %s\n", pam_strerror(pamh, ret)); } fprintf(stderr, "Re-initalizing creds...\n"); ret = pam_setcred(pamh, PAM_REINITIALIZE_CRED); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_setcred PAM_REINITIALIZE_CRED failed: %s\n", pam_strerror(pamh, ret)); } /* * Pretend user is logging out done, clean up and get out. */ fprintf(stderr, "Removing creds...\n"); ret = pam_setcred(pamh, PAM_DELETE_CRED); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_setcred PAM_DELETE_CRED failed: %s\n", pam_strerror(pamh, ret)); } fprintf(stderr, "Closing session...\n"); ret = pam_close_session(pamh, 0); if (ret != PAM_SUCCESS) { fprintf(stderr, "pam_open_session failed: %s\n", pam_strerror(pamh, ret)); } fprintf(stderr, "PAM end.\n"); pam_end(pamh, ret); }