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