Merge remote-tracking branch 'origin/master'
[unleashed/lotheac.git] / usr / src / lib / pam_modules / dial_auth / dial_auth.c
blob29b0a4455bc2b6d4be5f98ca29fdf4fb4e974e21
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
28 #include <crypt.h>
29 #include <pwd.h>
30 #include <shadow.h>
31 #include <string.h>
32 #include <stdlib.h>
33 #include <syslog.h>
34 #include <security/pam_appl.h>
35 #include <security/pam_modules.h>
36 #include "../../libpam/pam_impl.h"
38 #include <libintl.h>
41 * Various useful files and string constants
43 #define DIAL_FILE "/etc/dialups"
44 #define DPASS_FILE "/etc/d_passwd"
45 #define SHELL "/usr/bin/sh"
46 #define SCPYN(a, b) (void) strncpy(a, b, sizeof (a))
49 * pam_sm_authenticate - This is the top level function in the
50 * module called by pam_auth_port in the framework
51 * Returns: PAM_AUTH_ERR on failure, 0 on success
53 /*ARGSUSED*/
54 int
55 pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
57 char *ttyn, *user;
58 FILE *fp;
59 char defpass[30];
60 char line[80];
61 char *p1 = NULL, *p2 = NULL;
62 struct passwd pwd;
63 struct passwd *pwdp;
64 char pwd_buffer[1024];
65 char *password = NULL;
66 int retcode;
67 int i;
68 int debug = 0;
69 int res;
71 for (i = 0; i < argc; i++) {
72 if (strcasecmp(argv[i], "debug") == 0)
73 debug = 1;
74 else
75 syslog(LOG_DEBUG, "illegal option %s", argv[i]);
78 if ((retcode = pam_get_user(pamh, &user, NULL))
79 != PAM_SUCCESS ||
80 (retcode = pam_get_item(pamh, PAM_TTY, (void **)&ttyn))
81 != PAM_SUCCESS)
82 return (retcode);
84 if (debug) {
85 syslog(LOG_DEBUG,
86 "Dialpass authenticate user = %s, ttyn = %s",
87 user ? user : "NULL", ttyn ? ttyn : "NULL");
90 if (ttyn == NULL || *ttyn == '\0') {
91 char *service;
93 (void) pam_get_item(pamh, PAM_SERVICE, (void **)&service);
94 syslog(LOG_ERR, "pam_dial_auth: terminal-device not specified"
95 "by %s, returning %s.", service,
96 pam_strerror(pamh, PAM_SERVICE_ERR));
97 return (PAM_SERVICE_ERR);
99 getpwnam_r(user, &pwd, pwd_buffer, sizeof (pwd_buffer), &pwdp);
100 if (!pwdp)
101 return (PAM_USER_UNKNOWN);
103 if ((fp = fopen(DIAL_FILE, "rF")) == NULL)
104 return (PAM_IGNORE);
106 while ((p1 = fgets(line, sizeof (line), fp)) != NULL) {
107 while (*p1 != '\n' && *p1 != ' ' && *p1 != '\t')
108 p1++;
109 *p1 = '\0';
110 if (strcmp(line, ttyn) == 0)
111 break;
114 (void) fclose(fp);
116 if ((fp = fopen(DPASS_FILE, "rF")) == NULL) {
117 syslog(LOG_ERR, "pam_dial_auth: %s without %s, returning %s.",
118 DIAL_FILE, DPASS_FILE,
119 pam_strerror(pamh, PAM_SYSTEM_ERR));
120 (void) memset(line, 0, sizeof (line));
121 return (PAM_SYSTEM_ERR);
124 if (p1 == NULL) {
125 (void) fclose(fp);
126 (void) memset(line, 0, sizeof (line));
127 return (PAM_IGNORE);
130 defpass[0] = '\0';
132 while ((p1 = fgets(line, sizeof (line)-1, fp)) != NULL) {
133 while (*p1 && *p1 != ':')
134 p1++;
135 *p1++ = '\0';
136 p2 = p1;
137 while (*p1 && *p1 != ':')
138 p1++;
139 *p1 = '\0';
140 if (pwd.pw_shell != NULL && strcmp(pwd.pw_shell, line) == 0)
141 break;
143 if (strcmp(SHELL, line) == 0)
144 SCPYN(defpass, p2);
145 p2 = NULL;
148 (void) memset(line, 0, sizeof (line));
149 (void) fclose(fp);
151 if (p2 == NULL)
152 p2 = defpass;
154 if (*p2 != '\0') {
155 res = __pam_get_authtok(pamh, PAM_PROMPT, PAM_AUTHTOK,
156 dgettext(TEXT_DOMAIN, "Dialup Password: "), &password);
158 if (res != PAM_SUCCESS) {
159 return (res);
162 if (strcmp(crypt(password, p2), p2) != 0) {
163 (void) memset(password, 0, strlen(password));
164 free(password);
165 return (PAM_AUTH_ERR);
167 (void) memset(password, 0, strlen(password));
168 free(password);
171 return (PAM_SUCCESS);
175 * dummy pam_sm_setcred - does nothing
177 /*ARGSUSED*/
179 pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv)
181 return (PAM_IGNORE);