pam_unix.c revision 255376
199158Sdes/*- 2115619Sdes * Copyright (c) 2002-2003 Networks Associates Technology, Inc. 3228692Sdes * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav 499158Sdes * All rights reserved. 599158Sdes * 699158Sdes * This software was developed for the FreeBSD Project by ThinkSec AS and 799158Sdes * Network Associates Laboratories, the Security Research Division of 899158Sdes * Network Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 999158Sdes * ("CBOSS"), as part of the DARPA CHATS research program. 1099158Sdes * 1199158Sdes * Redistribution and use in source and binary forms, with or without 1299158Sdes * modification, are permitted provided that the following conditions 1399158Sdes * are met: 1499158Sdes * 1. Redistributions of source code must retain the above copyright 1599158Sdes * notice, this list of conditions and the following disclaimer. 1699158Sdes * 2. Redistributions in binary form must reproduce the above copyright 1799158Sdes * notice, this list of conditions and the following disclaimer in the 1899158Sdes * documentation and/or other materials provided with the distribution. 1999158Sdes * 3. The name of the author may not be used to endorse or promote 2099158Sdes * products derived from this software without specific prior written 2199158Sdes * permission. 2299158Sdes * 2399158Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2499158Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2599158Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2699158Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2799158Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2899158Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2999158Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 3099158Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3199158Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3299158Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3399158Sdes * SUCH DAMAGE. 3499158Sdes * 35255376Sdes * $Id: pam_unix.c 648 2013-03-05 17:54:27Z des $ 3699158Sdes */ 3799158Sdes 38117610Sdes#ifdef HAVE_CONFIG_H 39228692Sdes# include "config.h" 40117610Sdes#endif 41117610Sdes 4299158Sdes#include <sys/param.h> 4399158Sdes 4499158Sdes#include <pwd.h> 4599158Sdes#include <stdlib.h> 4699158Sdes#include <stdio.h> 4799158Sdes#include <string.h> 4899158Sdes#include <unistd.h> 4999158Sdes 50117610Sdes#ifdef HAVE_CRYPT_H 51117610Sdes# include <crypt.h> 52115619Sdes#endif 53115619Sdes 5499158Sdes#include <security/pam_modules.h> 55107937Sdes#include <security/pam_appl.h> 5699158Sdes 57174832Sdes#ifndef OPENPAM 5899158Sdesstatic char password_prompt[] = "Password:"; 5999158Sdes#endif 6099158Sdes 6199158Sdes#ifndef PAM_EXTERN 6299158Sdes#define PAM_EXTERN 6399158Sdes#endif 6499158Sdes 6599158SdesPAM_EXTERN int 6699158Sdespam_sm_authenticate(pam_handle_t *pamh, int flags, 6799158Sdes int argc, const char *argv[]) 6899158Sdes{ 69174832Sdes#ifndef OPENPAM 7099158Sdes struct pam_conv *conv; 7199158Sdes struct pam_message msg; 7299158Sdes const struct pam_message *msgp; 7399158Sdes struct pam_response *resp; 7499158Sdes#endif 7599158Sdes struct passwd *pwd; 7699158Sdes const char *user; 7799158Sdes char *crypt_password, *password; 7899158Sdes int pam_err, retry; 7999158Sdes 80174832Sdes (void)argc; 81174832Sdes (void)argv; 82174832Sdes 8399158Sdes /* identify user */ 8499158Sdes if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS) 8599158Sdes return (pam_err); 8699158Sdes if ((pwd = getpwnam(user)) == NULL) 8799158Sdes return (PAM_USER_UNKNOWN); 8899158Sdes 8999158Sdes /* get password */ 90174832Sdes#ifndef OPENPAM 9199158Sdes pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv); 9299158Sdes if (pam_err != PAM_SUCCESS) 9399158Sdes return (PAM_SYSTEM_ERR); 9499158Sdes msg.msg_style = PAM_PROMPT_ECHO_OFF; 9599158Sdes msg.msg = password_prompt; 9699158Sdes msgp = &msg; 9799158Sdes#endif 9899158Sdes for (retry = 0; retry < 3; ++retry) { 99174832Sdes#ifdef OPENPAM 10099158Sdes pam_err = pam_get_authtok(pamh, PAM_AUTHTOK, 10199158Sdes (const char **)&password, NULL); 10299158Sdes#else 10399158Sdes resp = NULL; 10499158Sdes pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr); 10599158Sdes if (resp != NULL) { 10699158Sdes if (pam_err == PAM_SUCCESS) 10799158Sdes password = resp->resp; 10899158Sdes else 10999158Sdes free(resp->resp); 11099158Sdes free(resp); 11199158Sdes } 11299158Sdes#endif 11399158Sdes if (pam_err == PAM_SUCCESS) 11499158Sdes break; 11599158Sdes } 11699158Sdes if (pam_err == PAM_CONV_ERR) 11799158Sdes return (pam_err); 11899158Sdes if (pam_err != PAM_SUCCESS) 11999158Sdes return (PAM_AUTH_ERR); 12099158Sdes 12199158Sdes /* compare passwords */ 12299158Sdes if ((!pwd->pw_passwd[0] && (flags & PAM_DISALLOW_NULL_AUTHTOK)) || 12399158Sdes (crypt_password = crypt(password, pwd->pw_passwd)) == NULL || 12499158Sdes strcmp(crypt_password, pwd->pw_passwd) != 0) 12599158Sdes pam_err = PAM_AUTH_ERR; 12699158Sdes else 12799158Sdes pam_err = PAM_SUCCESS; 128174832Sdes#ifndef OPENPAM 12999158Sdes free(password); 13099158Sdes#endif 13199158Sdes return (pam_err); 13299158Sdes} 13399158Sdes 13499158SdesPAM_EXTERN int 13599158Sdespam_sm_setcred(pam_handle_t *pamh, int flags, 13699158Sdes int argc, const char *argv[]) 13799158Sdes{ 13899158Sdes 139174832Sdes (void)pamh; 140174832Sdes (void)flags; 141174832Sdes (void)argc; 142174832Sdes (void)argv; 14399158Sdes return (PAM_SUCCESS); 14499158Sdes} 14599158Sdes 14699158SdesPAM_EXTERN int 14799158Sdespam_sm_acct_mgmt(pam_handle_t *pamh, int flags, 14899158Sdes int argc, const char *argv[]) 14999158Sdes{ 15099158Sdes 151174832Sdes (void)pamh; 152174832Sdes (void)flags; 153174832Sdes (void)argc; 154174832Sdes (void)argv; 15599158Sdes return (PAM_SUCCESS); 15699158Sdes} 15799158Sdes 15899158SdesPAM_EXTERN int 15999158Sdespam_sm_open_session(pam_handle_t *pamh, int flags, 16099158Sdes int argc, const char *argv[]) 16199158Sdes{ 16299158Sdes 163174832Sdes (void)pamh; 164174832Sdes (void)flags; 165174832Sdes (void)argc; 166174832Sdes (void)argv; 16799158Sdes return (PAM_SUCCESS); 16899158Sdes} 16999158Sdes 17099158SdesPAM_EXTERN int 17199158Sdespam_sm_close_session(pam_handle_t *pamh, int flags, 17299158Sdes int argc, const char *argv[]) 17399158Sdes{ 17499158Sdes 175174832Sdes (void)pamh; 176174832Sdes (void)flags; 177174832Sdes (void)argc; 178174832Sdes (void)argv; 17999158Sdes return (PAM_SUCCESS); 18099158Sdes} 18199158Sdes 18299158SdesPAM_EXTERN int 18399158Sdespam_sm_chauthtok(pam_handle_t *pamh, int flags, 18499158Sdes int argc, const char *argv[]) 18599158Sdes{ 18699158Sdes 187174832Sdes (void)pamh; 188174832Sdes (void)flags; 189174832Sdes (void)argc; 190174832Sdes (void)argv; 19199158Sdes return (PAM_SERVICE_ERR); 19299158Sdes} 19399158Sdes 19499158Sdes#ifdef PAM_MODULE_ENTRY 19599158SdesPAM_MODULE_ENTRY("pam_unix"); 19699158Sdes#endif 197