2
* Copyright Alexander O. Yuriev, 1996. All rights reserved.
3
* NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>
4
* Copyright Jan R�korajski, 1999. All rights reserved.
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
9
* 1. Redistributions of source code must retain the above copyright
10
* notice, and the entire permission notice in its entirety,
11
* including the disclaimer of warranties.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. The name of the author may not be used to endorse or promote
16
* products derived from this software without specific prior
19
* ALTERNATIVELY, this product may be distributed under the terms of
20
* the GNU Public License, in which case the provisions of the GPL are
21
* required INSTEAD OF the above restrictions. (This clause is
22
* necessary due to a potential bad interaction between the GPL and
23
* the restrictions contained in a BSD-style copyright.)
25
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
26
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
29
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
30
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
33
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
35
* OF THE POSSIBILITY OF SUCH DAMAGE.
40
#include <security/_pam_aconf.h>
49
#include <sys/types.h>
52
/* indicate the following groups are defined */
56
#define _PAM_EXTERN_FUNCTIONS
57
#include <security/_pam_macros.h>
58
#include <security/pam_modules.h>
61
#include <security/pam_appl.h>
62
#endif /* LINUX_PAM */
67
* PAM framework looks for these entry-points to pass control to the
68
* authentication module.
73
* pam_sm_authenticate() performs UNIX/shadow authentication
75
* First, if shadow support is available, attempt to perform
76
* authentication using shadow passwords. If shadow is not
77
* available, or user does not have a shadow password, fallback
78
* onto a normal UNIX authentication
81
#define _UNIX_AUTHTOK "-UN*X-PASS"
85
if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) { \
86
D(("recording return code for next time [%d]", \
89
pam_set_data(pamh, "unix_setcred_return", \
90
(void *) ret_data, setcred_free); \
92
D(("done. [%s]", pam_strerror(pamh, retval))); \
97
static void setcred_free (pam_handle_t * pamh, void *ptr, int err)
104
PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
105
,int argc, const char **argv)
108
int retval, *ret_data = NULL;
109
const char *name, *p;
113
ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
115
/* Get a few bytes so we can pass our return value to
117
if (on(UNIX_LIKE_AUTH, ctrl))
118
ret_data = malloc(sizeof(int));
120
/* get the user'name' */
122
retval = pam_get_user(pamh, &name, NULL);
123
if (retval == PAM_SUCCESS) {
125
* Various libraries at various times have had bugs related to
126
* '+' or '-' as the first character of a user name. Don't take
127
* any chances here. Require that the username starts with an
128
* alphanumeric character.
130
if (name == NULL || !isalnum(*name)) {
131
_log_err(LOG_ERR, pamh, "bad username [%s]", name);
132
retval = PAM_USER_UNKNOWN;
135
if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
136
D(("username [%s] obtained", name));
138
D(("trouble reading username"));
139
if (retval == PAM_CONV_AGAIN) {
140
D(("pam_get_user/conv() function is not ready yet"));
141
/* it is safe to resume this function so we translate this
142
* retval to the value that indicates we're happy to resume.
144
retval = PAM_INCOMPLETE;
149
/* if this user does not have a password... */
151
if (_unix_blankpasswd(ctrl, pamh, name)) {
152
D(("user '%s' has blank passwd", name));
154
retval = PAM_SUCCESS;
157
/* get this user's authentication token */
159
retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL
161
if (retval != PAM_SUCCESS) {
162
if (retval != PAM_CONV_AGAIN) {
163
_log_err(LOG_CRIT, pamh, "auth could not identify password for [%s]"
166
D(("conversation function is not ready yet"));
168
* it is safe to resume this function so we translate this
169
* retval to the value that indicates we're happy to resume.
171
retval = PAM_INCOMPLETE;
176
D(("user=%s, password=[%s]", name, p));
178
/* verify the password of this user */
179
retval = _unix_verify_password(pamh, name, p, ctrl);
187
* The only thing _pam_set_credentials_unix() does is initialization of
190
* Well, everybody but me on linux-pam is convinced that it should not
191
* initialize group IDs, so I am not doing it but don't say that I haven't
195
PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags
196
,int argc, const char **argv)
203
retval = PAM_SUCCESS;
205
D(("recovering return code from auth call"));
206
/* We will only find something here if UNIX_LIKE_AUTH is set --
207
don't worry about an explicit check of argv. */
208
pam_get_data(pamh, "unix_setcred_return", (const void **) &pretval);
211
pam_set_data(pamh, "unix_setcred_return", NULL, NULL);
212
D(("recovered data indicates that old retval was %d", retval));
219
struct pam_module _pam_unix_auth_modstruct = {