17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*004388ebScasper  * Common Development and Distribution License (the "License").
6*004388ebScasper  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*004388ebScasper  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include <crypt.h>
277c478bd9Sstevel@tonic-gate #include <pwd.h>
287c478bd9Sstevel@tonic-gate #include <shadow.h>
297c478bd9Sstevel@tonic-gate #include <string.h>
307c478bd9Sstevel@tonic-gate #include <stdlib.h>
317c478bd9Sstevel@tonic-gate #include <syslog.h>
327c478bd9Sstevel@tonic-gate #include <security/pam_appl.h>
337c478bd9Sstevel@tonic-gate #include <security/pam_modules.h>
347c478bd9Sstevel@tonic-gate #include "../../libpam/pam_impl.h"
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <libintl.h>
377c478bd9Sstevel@tonic-gate 
387c478bd9Sstevel@tonic-gate /*
397c478bd9Sstevel@tonic-gate  * Various useful files and string constants
407c478bd9Sstevel@tonic-gate  */
417c478bd9Sstevel@tonic-gate #define	DIAL_FILE	"/etc/dialups"
427c478bd9Sstevel@tonic-gate #define	DPASS_FILE	"/etc/d_passwd"
437c478bd9Sstevel@tonic-gate #define	SHELL		"/usr/bin/sh"
447c478bd9Sstevel@tonic-gate #define	SCPYN(a, b)	(void) strncpy(a, b, sizeof (a))
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate /*
477c478bd9Sstevel@tonic-gate  * pam_sm_authenticate	- This is the top level function in the
487c478bd9Sstevel@tonic-gate  *			module called by pam_auth_port in the framework
497c478bd9Sstevel@tonic-gate  *			Returns: PAM_AUTH_ERR on failure, 0 on success
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate /*ARGSUSED*/
527c478bd9Sstevel@tonic-gate int
pam_sm_authenticate(pam_handle_t * pamh,int flags,int argc,const char ** argv)537c478bd9Sstevel@tonic-gate pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
547c478bd9Sstevel@tonic-gate {
557c478bd9Sstevel@tonic-gate 	char	*ttyn, *user;
567c478bd9Sstevel@tonic-gate 	FILE 	*fp;
577c478bd9Sstevel@tonic-gate 	char 	defpass[30];
587c478bd9Sstevel@tonic-gate 	char	line[80];
597c478bd9Sstevel@tonic-gate 	char 	*p1 = NULL, *p2 = NULL;
607c478bd9Sstevel@tonic-gate 	struct passwd 	pwd;
617c478bd9Sstevel@tonic-gate 	char	pwd_buffer[1024];
627c478bd9Sstevel@tonic-gate 	char	*password = NULL;
637c478bd9Sstevel@tonic-gate 	int	retcode;
647c478bd9Sstevel@tonic-gate 	int	i;
657c478bd9Sstevel@tonic-gate 	int	debug = 0;
667c478bd9Sstevel@tonic-gate 	int	res;
677c478bd9Sstevel@tonic-gate 
687c478bd9Sstevel@tonic-gate 	for (i = 0; i < argc; i++) {
697c478bd9Sstevel@tonic-gate 		if (strcasecmp(argv[i], "debug") == 0)
707c478bd9Sstevel@tonic-gate 			debug = 1;
717c478bd9Sstevel@tonic-gate 		else
727c478bd9Sstevel@tonic-gate 			syslog(LOG_DEBUG, "illegal option %s", argv[i]);
737c478bd9Sstevel@tonic-gate 	}
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 	if ((retcode = pam_get_user(pamh, &user, NULL))
767c478bd9Sstevel@tonic-gate 					!= PAM_SUCCESS ||
777c478bd9Sstevel@tonic-gate 	    (retcode = pam_get_item(pamh, PAM_TTY, (void **)&ttyn))
787c478bd9Sstevel@tonic-gate 					!= PAM_SUCCESS)
797c478bd9Sstevel@tonic-gate 		return (retcode);
807c478bd9Sstevel@tonic-gate 
817c478bd9Sstevel@tonic-gate 	if (debug) {
827c478bd9Sstevel@tonic-gate 		syslog(LOG_DEBUG,
837c478bd9Sstevel@tonic-gate 			"Dialpass authenticate user = %s, ttyn = %s",
847c478bd9Sstevel@tonic-gate 			user ? user : "NULL", ttyn ? ttyn : "NULL");
857c478bd9Sstevel@tonic-gate 	}
867c478bd9Sstevel@tonic-gate 
877c478bd9Sstevel@tonic-gate 	if (ttyn == NULL || *ttyn == '\0') {
887c478bd9Sstevel@tonic-gate 		char *service;
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate 		(void) pam_get_item(pamh, PAM_SERVICE, (void **)&service);
917c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "pam_dial_auth: terminal-device not specified"
927c478bd9Sstevel@tonic-gate 		    "by %s, returning %s.", service,
937c478bd9Sstevel@tonic-gate 		    pam_strerror(pamh, PAM_SERVICE_ERR));
947c478bd9Sstevel@tonic-gate 		return (PAM_SERVICE_ERR);
957c478bd9Sstevel@tonic-gate 	}
967c478bd9Sstevel@tonic-gate 	if (getpwnam_r(user, &pwd, pwd_buffer, sizeof (pwd_buffer)) == NULL)
977c478bd9Sstevel@tonic-gate 		return (PAM_USER_UNKNOWN);
987c478bd9Sstevel@tonic-gate 
99*004388ebScasper 	if ((fp = fopen(DIAL_FILE, "rF")) == NULL)
1007c478bd9Sstevel@tonic-gate 		return (PAM_IGNORE);
1017c478bd9Sstevel@tonic-gate 
1027c478bd9Sstevel@tonic-gate 	while ((p1 = fgets(line, sizeof (line), fp)) != NULL) {
1037c478bd9Sstevel@tonic-gate 		while (*p1 != '\n' && *p1 != ' ' && *p1 != '\t')
1047c478bd9Sstevel@tonic-gate 			p1++;
1057c478bd9Sstevel@tonic-gate 		*p1 = '\0';
1067c478bd9Sstevel@tonic-gate 		if (strcmp(line, ttyn) == 0)
1077c478bd9Sstevel@tonic-gate 			break;
1087c478bd9Sstevel@tonic-gate 	}
1097c478bd9Sstevel@tonic-gate 
1107c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
1117c478bd9Sstevel@tonic-gate 
112*004388ebScasper 	if ((fp = fopen(DPASS_FILE, "rF")) == NULL) {
1137c478bd9Sstevel@tonic-gate 		syslog(LOG_ERR, "pam_dial_auth: %s without %s, returning %s.",
1147c478bd9Sstevel@tonic-gate 		    DIAL_FILE, DPASS_FILE,
1157c478bd9Sstevel@tonic-gate 		    pam_strerror(pamh, PAM_SYSTEM_ERR));
1167c478bd9Sstevel@tonic-gate 		(void) memset(line, 0, sizeof (line));
1177c478bd9Sstevel@tonic-gate 		return (PAM_SYSTEM_ERR);
1187c478bd9Sstevel@tonic-gate 	}
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate 	if (p1 == NULL) {
1217c478bd9Sstevel@tonic-gate 		(void) fclose(fp);
1227c478bd9Sstevel@tonic-gate 		(void) memset(line, 0, sizeof (line));
1237c478bd9Sstevel@tonic-gate 		return (PAM_IGNORE);
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate 	defpass[0] = '\0';
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 	while ((p1 = fgets(line, sizeof (line)-1, fp)) != NULL) {
1297c478bd9Sstevel@tonic-gate 		while (*p1 && *p1 != ':')
1307c478bd9Sstevel@tonic-gate 			p1++;
1317c478bd9Sstevel@tonic-gate 		*p1++ = '\0';
1327c478bd9Sstevel@tonic-gate 		p2 = p1;
1337c478bd9Sstevel@tonic-gate 		while (*p1 && *p1 != ':')
1347c478bd9Sstevel@tonic-gate 			p1++;
1357c478bd9Sstevel@tonic-gate 		*p1 = '\0';
1367c478bd9Sstevel@tonic-gate 		if (pwd.pw_shell != NULL && strcmp(pwd.pw_shell, line) == 0)
1377c478bd9Sstevel@tonic-gate 			break;
1387c478bd9Sstevel@tonic-gate 
1397c478bd9Sstevel@tonic-gate 		if (strcmp(SHELL, line) == 0)
1407c478bd9Sstevel@tonic-gate 			SCPYN(defpass, p2);
1417c478bd9Sstevel@tonic-gate 		p2 = NULL;
1427c478bd9Sstevel@tonic-gate 	}
1437c478bd9Sstevel@tonic-gate 
1447c478bd9Sstevel@tonic-gate 	(void) memset(line, 0, sizeof (line));
1457c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
1467c478bd9Sstevel@tonic-gate 
1477c478bd9Sstevel@tonic-gate 	if (p2 == NULL)
1487c478bd9Sstevel@tonic-gate 		p2 = defpass;
1497c478bd9Sstevel@tonic-gate 
1507c478bd9Sstevel@tonic-gate 	if (*p2 != '\0') {
1517c478bd9Sstevel@tonic-gate 		res = __pam_get_authtok(pamh, PAM_PROMPT, PAM_AUTHTOK,
1527c478bd9Sstevel@tonic-gate 		    dgettext(TEXT_DOMAIN, "Dialup Password: "), &password);
1537c478bd9Sstevel@tonic-gate 
1547c478bd9Sstevel@tonic-gate 		if (res != PAM_SUCCESS) {
1557c478bd9Sstevel@tonic-gate 			return (res);
1567c478bd9Sstevel@tonic-gate 		}
1577c478bd9Sstevel@tonic-gate 
1587c478bd9Sstevel@tonic-gate 		if (strcmp(crypt(password, p2), p2) != 0) {
1597c478bd9Sstevel@tonic-gate 			(void) memset(password, 0, strlen(password));
1607c478bd9Sstevel@tonic-gate 			free(password);
1617c478bd9Sstevel@tonic-gate 			return (PAM_AUTH_ERR);
1627c478bd9Sstevel@tonic-gate 		}
1637c478bd9Sstevel@tonic-gate 		(void) memset(password, 0, strlen(password));
1647c478bd9Sstevel@tonic-gate 		free(password);
1657c478bd9Sstevel@tonic-gate 	}
1667c478bd9Sstevel@tonic-gate 
1677c478bd9Sstevel@tonic-gate 	return (PAM_SUCCESS);
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate /*
1717c478bd9Sstevel@tonic-gate  * dummy pam_sm_setcred - does nothing
1727c478bd9Sstevel@tonic-gate  */
1737c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1747c478bd9Sstevel@tonic-gate int
pam_sm_setcred(pam_handle_t * pamh,int flags,int argc,const char ** argv)1757c478bd9Sstevel@tonic-gate pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
1767c478bd9Sstevel@tonic-gate {
1777c478bd9Sstevel@tonic-gate 	return (PAM_IGNORE);
1787c478bd9Sstevel@tonic-gate }
179