pam_unix.c revision 107937
129415Sjmg/*-
2119853Scg * Copyright (c) 2002 Networks Associates Technology, Inc.
339899Sluigi * All rights reserved.
429415Sjmg *
529415Sjmg * This software was developed for the FreeBSD Project by ThinkSec AS and
629415Sjmg * Network Associates Laboratories, the Security Research Division of
729415Sjmg * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
850723Scg * ("CBOSS"), as part of the DARPA CHATS research program.
950723Scg *
1029415Sjmg * Redistribution and use in source and binary forms, with or without
1129415Sjmg * modification, are permitted provided that the following conditions
1230869Sjmg * are met:
1330869Sjmg * 1. Redistributions of source code must retain the above copyright
1430869Sjmg *    notice, this list of conditions and the following disclaimer.
1530869Sjmg * 2. Redistributions in binary form must reproduce the above copyright
1650723Scg *    notice, this list of conditions and the following disclaimer in the
1750723Scg *    documentation and/or other materials provided with the distribution.
1830869Sjmg * 3. The name of the author may not be used to endorse or promote
1950723Scg *    products derived from this software without specific prior written
2050723Scg *    permission.
2150723Scg *
2250723Scg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2350723Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2450723Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2550723Scg * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2650723Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2750723Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2850723Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2950723Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3029415Sjmg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3129415Sjmg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3253465Scg * SUCH DAMAGE.
3329415Sjmg *
3453465Scg * $P4: //depot/projects/openpam/modules/pam_unix/pam_unix.c#3 $
3553553Stanimura */
3629415Sjmg
37110499Snyan#include <sys/param.h>
38110499Snyan
3970134Scg#include <pwd.h>
4070134Scg#include <stdlib.h>
4182180Scg#include <stdio.h>
4282180Scg#include <string.h>
4367803Scg#include <unistd.h>
4455706Scg
4555254Scg#include <security/pam_modules.h>
4667803Scg#include <security/pam_appl.h>
4750723Scg
4850723Scg#ifndef _OPENPAM
4964881Scgstatic char password_prompt[] = "Password:";
5050723Scg#endif
5174763Scg
5229415Sjmg#ifndef PAM_EXTERN
5367803Scg#define PAM_EXTERN
5464881Scg#endif
5550723Scg
5664881ScgPAM_EXTERN int
5750723Scgpam_sm_authenticate(pam_handle_t *pamh, int flags,
5874763Scg	int argc, const char *argv[])
5929415Sjmg{
6064881Scg#ifndef _OPENPAM
6164881Scg	struct pam_conv *conv;
6264881Scg	struct pam_message msg;
6364881Scg	const struct pam_message *msgp;
6464881Scg	struct pam_response *resp;
6564881Scg#endif
6654462Scg	struct passwd *pwd;
6774763Scg	const char *user;
6854462Scg	char *crypt_password, *password;
6950723Scg	int pam_err, retry;
7029415Sjmg
7150723Scg	/* identify user */
7250723Scg	if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
7374763Scg		return (pam_err);
7474763Scg	if ((pwd = getpwnam(user)) == NULL)
7567803Scg		return (PAM_USER_UNKNOWN);
7667803Scg
7750723Scg	/* get password */
7829415Sjmg#ifndef _OPENPAM
7950723Scg	pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
8050723Scg	if (pam_err != PAM_SUCCESS)
8150723Scg		return (PAM_SYSTEM_ERR);
8254462Scg	msg.msg_style = PAM_PROMPT_ECHO_OFF;
8354462Scg	msg.msg = password_prompt;
8465644Scg	msgp = &msg;
8555706Scg#endif
8629415Sjmg	for (retry = 0; retry < 3; ++retry) {
8784111Scg#ifdef _OPENPAM
8850723Scg		pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
8950723Scg		    (const char **)&password, NULL);
9070291Scg#else
9150723Scg		resp = NULL;
9274763Scg		pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
9350723Scg		if (resp != NULL) {
9450723Scg			if (pam_err == PAM_SUCCESS)
9584111Scg				password = resp->resp;
9674763Scg			else
9774763Scg				free(resp->resp);
9850723Scg			free(resp);
9950723Scg		}
10050723Scg#endif
10167803Scg		if (pam_err == PAM_SUCCESS)
10250723Scg			break;
10350723Scg	}
10450723Scg	if (pam_err == PAM_CONV_ERR)
10550723Scg		return (pam_err);
10654462Scg	if (pam_err != PAM_SUCCESS)
10729415Sjmg		return (PAM_AUTH_ERR);
10850723Scg
10984111Scg	/* compare passwords */
11050723Scg	if ((!pwd->pw_passwd[0] && (flags & PAM_DISALLOW_NULL_AUTHTOK)) ||
11129415Sjmg	    (crypt_password = crypt(password, pwd->pw_passwd)) == NULL ||
11250723Scg	    strcmp(crypt_password, pwd->pw_passwd) != 0)
11329415Sjmg		pam_err = PAM_AUTH_ERR;
11450723Scg	else
11550723Scg		pam_err = PAM_SUCCESS;
11650723Scg#ifndef _OPENPAM
11750723Scg	free(password);
11829415Sjmg#endif
11929415Sjmg	return (pam_err);
12084111Scg}
12184111Scg
12284111ScgPAM_EXTERN int
12384111Scgpam_sm_setcred(pam_handle_t *pamh, int flags,
12484111Scg	int argc, const char *argv[])
12584111Scg{
12684111Scg
127129180Struckman	return (PAM_SUCCESS);
128129180Struckman}
129129180Struckman
130129180StruckmanPAM_EXTERN int
131129180Struckmanpam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
132129180Struckman	int argc, const char *argv[])
13384111Scg{
13484111Scg
13584111Scg	return (PAM_SUCCESS);
13684111Scg}
13784111Scg
13829415SjmgPAM_EXTERN int
13950723Scgpam_sm_open_session(pam_handle_t *pamh, int flags,
14029415Sjmg	int argc, const char *argv[])
14167803Scg{
14250723Scg
14329415Sjmg	return (PAM_SUCCESS);
14450723Scg}
14550723Scg
14650723ScgPAM_EXTERN int
147108064Ssemenupam_sm_close_session(pam_handle_t *pamh, int flags,
14829415Sjmg	int argc, const char *argv[])
14929415Sjmg{
15029415Sjmg
15150723Scg	return (PAM_SUCCESS);
15229415Sjmg}
15350723Scg
15450723ScgPAM_EXTERN int
15529415Sjmgpam_sm_chauthtok(pam_handle_t *pamh, int flags,
15650723Scg	int argc, const char *argv[])
15750723Scg{
15850723Scg
15950723Scg	return (PAM_SERVICE_ERR);
16029415Sjmg}
16129415Sjmg
16250723Scg#ifdef PAM_MODULE_ENTRY
16350723ScgPAM_MODULE_ENTRY("pam_unix");
16429415Sjmg#endif
16550723Scg