1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #include "ldap_headers.h" 28 29 /* 30 * 31 * LDAP module for pam_sm_authenticate. 32 * 33 * options - 34 * 35 * debug 36 * nowarn 37 */ 38 39 /* 40 * pam_sm_authenticate(): 41 * Authenticate user. 42 */ 43 /*ARGSUSED*/ 44 int 45 pam_sm_authenticate( 46 pam_handle_t *pamh, 47 int flags, 48 int argc, 49 const char **argv) 50 { 51 char *service = NULL; 52 char *user = NULL; 53 int err; 54 int result = PAM_AUTH_ERR; 55 int debug = 0; 56 int i; 57 char *password = NULL; 58 ns_cred_t *credp = NULL; 59 int nowarn = 0; 60 61 /* Get the service and user */ 62 if ((err = pam_get_item(pamh, PAM_SERVICE, (void **)&service)) 63 != PAM_SUCCESS || 64 (err = pam_get_item(pamh, PAM_USER, (void **)&user)) != PAM_SUCCESS) 65 return (err); 66 67 /* 68 * Check options passed to this module. 69 * Silently ignore try_first_pass and use_first_pass options 70 * for the time being. 71 */ 72 for (i = 0; i < argc; i++) { 73 if (strcmp(argv[i], "debug") == 0) 74 debug = 1; 75 else if (strcmp(argv[i], "nowarn") == 0) 76 nowarn = 1; 77 else if ((strcmp(argv[i], "try_first_pass") != 0) && 78 (strcmp(argv[i], "use_first_pass") != 0)) 79 syslog(LOG_AUTH | LOG_DEBUG, 80 "ldap pam_sm_authenticate(%s), " 81 "illegal scheme option %s", service, argv[i]); 82 } 83 84 if (debug) 85 syslog(LOG_AUTH | LOG_DEBUG, 86 "ldap pam_sm_authenticate(%s %s), flags = %x %s", 87 service, (user && *user != '\0')?user:"no-user", flags, 88 (nowarn)? ", nowarn": ""); 89 90 if (!user || *user == '\0') 91 return (PAM_USER_UNKNOWN); 92 93 /* Get the password entered in the first scheme if any */ 94 (void) pam_get_item(pamh, PAM_AUTHTOK, (void **) &password); 95 if (password == NULL) { 96 if (debug) 97 syslog(LOG_AUTH | LOG_DEBUG, 98 "ldap pam_sm_authenticate(%s %s), " 99 "AUTHTOK not set", service, user); 100 return (PAM_AUTH_ERR); 101 } 102 103 /* 104 * Authenticate user using the password from PAM_AUTHTOK. 105 * If no password available or if authentication fails 106 * return the appropriate error. 107 */ 108 result = authenticate(&credp, user, password, NULL); 109 if (result == PAM_NEW_AUTHTOK_REQD) { 110 /* 111 * PAM_NEW_AUTHTOK_REQD means the 112 * user's password is good but needs 113 * to change immediately. If the service 114 * is login or similar programs, the 115 * user will be asked to change the 116 * password after the account management 117 * module is called and determined that 118 * the password has expired. 119 * So change the rc to PAM_SUCCESS here. 120 */ 121 result = PAM_SUCCESS; 122 } else if (result == PAM_AUTHTOK_EXPIRED) { 123 /* 124 * Authentication token is the right one but 125 * expired. Consider this as pass. 126 * Change rc to PAM_SUCCESS. 127 */ 128 result = PAM_SUCCESS; 129 } 130 131 if (credp != NULL) 132 (void) __ns_ldap_freeCred(&credp); 133 return (result); 134 } 135