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 * Copyright 2023 OmniOS Community Edition (OmniOSce) Association. 27 */ 28 29 #include "ldap_headers.h" 30 31 /* 32 * 33 * LDAP module for pam_sm_authenticate. 34 * 35 * options - 36 * 37 * debug 38 * nowarn 39 */ 40 41 /* 42 * pam_sm_authenticate(): 43 * Authenticate user. 44 */ 45 int 46 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) 47 { 48 const char *service = NULL; 49 const char *user = NULL; 50 int err; 51 int result = PAM_AUTH_ERR; 52 int debug = 0; 53 int i; 54 const char *password = NULL; 55 ns_cred_t *credp = NULL; 56 int nowarn = 0; 57 58 /* Get the service and user */ 59 if ((err = pam_get_item(pamh, PAM_SERVICE, (const void **)&service)) != 60 PAM_SUCCESS || 61 (err = pam_get_item(pamh, PAM_USER, (const void **)&user)) != 62 PAM_SUCCESS) { 63 return (err); 64 } 65 66 /* 67 * Check options passed to this module. 68 * Silently ignore try_first_pass and use_first_pass options 69 * for the time being. 70 */ 71 for (i = 0; i < argc; i++) { 72 if (strcmp(argv[i], "debug") == 0) 73 debug = 1; 74 else if (strcmp(argv[i], "nowarn") == 0) 75 nowarn = 1; 76 else if ((strcmp(argv[i], "try_first_pass") != 0) && 77 (strcmp(argv[i], "use_first_pass") != 0)) 78 syslog(LOG_AUTH | LOG_DEBUG, 79 "ldap pam_sm_authenticate(%s), " 80 "illegal scheme option %s", service, argv[i]); 81 } 82 83 if (debug) 84 syslog(LOG_AUTH | LOG_DEBUG, 85 "ldap pam_sm_authenticate(%s %s), flags = %x %s", 86 service, (user && *user != '\0')?user:"no-user", flags, 87 (nowarn)? ", nowarn": ""); 88 89 if (!user || *user == '\0') 90 return (PAM_USER_UNKNOWN); 91 92 /* Get the password entered in the first scheme if any */ 93 (void) pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password); 94 if (password == NULL) { 95 if (debug) 96 syslog(LOG_AUTH | LOG_DEBUG, 97 "ldap pam_sm_authenticate(%s %s), " 98 "AUTHTOK not set", service, user); 99 return (PAM_AUTH_ERR); 100 } 101 102 /* 103 * Authenticate user using the password from PAM_AUTHTOK. 104 * If no password available or if authentication fails 105 * return the appropriate error. 106 */ 107 result = authenticate(&credp, user, password, NULL); 108 if (result == PAM_NEW_AUTHTOK_REQD) { 109 /* 110 * PAM_NEW_AUTHTOK_REQD means the 111 * user's password is good but needs 112 * to change immediately. If the service 113 * is login or similar programs, the 114 * user will be asked to change the 115 * password after the account management 116 * module is called and determined that 117 * the password has expired. 118 * So change the rc to PAM_SUCCESS here. 119 */ 120 result = PAM_SUCCESS; 121 } else if (result == PAM_AUTHTOK_EXPIRED) { 122 /* 123 * Authentication token is the right one but 124 * expired. Consider this as pass. 125 * Change rc to PAM_SUCCESS. 126 */ 127 result = PAM_SUCCESS; 128 } 129 130 if (credp != NULL) 131 (void) __ns_ldap_freeCred(&credp); 132 return (result); 133 } 134