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
pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,const char ** argv)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