xref: /illumos-gate/usr/src/cmd/ttymon/tmutmp.c (revision 4f364e7c95ee7fd9d5bbeddc1940e92405bb0e72)
1 /*
2  * CDDL HEADER START
3  *
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.
7  *
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.
12  *
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]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 /*
30  * University Copyright- Copyright (c) 1982, 1986, 1988
31  * The Regents of the University of California
32  * All Rights Reserved
33  *
34  * University Acknowledgment- Portions of this document are derived from
35  * software developed by the University of California, Berkeley, and its
36  * contributors.
37  */
38 
39 #pragma ident	"%Z%%M%	%I%	%E% SMI"
40 
41 #include	<unistd.h>
42 #include	<stdlib.h>
43 #include	<stdio.h>
44 #include	<fcntl.h>
45 #include	<sys/types.h>
46 #include	<sys/wait.h>
47 #include	<string.h>
48 #include	<memory.h>
49 #include	<utmpx.h>
50 #include	<security/pam_appl.h>
51 
52 #include	"sac.h"
53 #include	"tmextern.h"
54 
55 extern	char	*lastname();
56 
57 /*
58  * account - create a utmpx record for service
59  *
60  */
61 
62 int
63 account(line)
64 char	*line;
65 {
66 	struct utmpx utmpx;			/* prototype utmpx entry */
67 	struct utmpx *up = &utmpx;		/* and a pointer to it */
68 
69 	(void) memset(up, '\0', sizeof (utmpx));
70 	up->ut_user[0] = '.';
71 	(void) strncpy(&up->ut_user[1], Tag, sizeof (up->ut_user)-1);
72 	(void) strncpy(up->ut_line, lastname(line), sizeof (up->ut_line));
73 	up->ut_pid = getpid();
74 	up->ut_type = USER_PROCESS;
75 	up->ut_id[0] = 't';
76 	up->ut_id[1] = 'm';
77 	up->ut_id[2] = SC_WILDC;
78 	up->ut_id[3] = SC_WILDC;
79 	up->ut_exit.e_termination = 0;
80 	up->ut_exit.e_exit = 0;
81 	(void) time(&up->ut_tv.tv_sec);
82 	if (makeutx(up) == NULL) {
83 		log("makeutx for pid %d failed", up->ut_pid);
84 		return (-1);
85 	}
86 	return (0);
87 }
88 
89 /*
90  * checkut_line	- check if a login is active on the requested device
91  */
92 int
93 checkut_line(char *line)
94 {
95 	struct utmpx *u;
96 	char buf[33], ttyn[33];
97 	int rvalue = 0;
98 	pid_t ownpid = getpid();
99 
100 	(void) strncpy(buf, lastname(line), sizeof (u->ut_line));
101 	buf[sizeof (u->ut_line)] = '\0';
102 
103 	setutxent();
104 	while ((u = getutxent()) != NULL) {
105 		if (u->ut_pid == ownpid) {
106 			if (u->ut_type == USER_PROCESS) {
107 				strncpy(ttyn, u->ut_line, sizeof (u->ut_line));
108 				ttyn[sizeof (u->ut_line)] = '\0';
109 				if (strcmp(buf, ttyn) == 0) {
110 					rvalue = 1;
111 					break;
112 				}
113 			}
114 		}
115 	}
116 	endutxent();
117 
118 	return (rvalue);
119 }
120 
121 
122 void
123 cleanut(pid, status)
124 	pid_t	pid;
125 	int	status;
126 {
127 	pam_handle_t *pamh;
128 	struct utmpx *up;
129 	struct utmpx ut;
130 	char user[33], ttyn[33], rhost[258];
131 
132 	setutxent();
133 	while (up = getutxent()) {
134 		if (up->ut_pid == pid) {
135 			if (up->ut_type == DEAD_PROCESS) {
136 				/* Cleaned up elsewhere. */
137 				break;
138 			}
139 
140 			strncpy(user, up->ut_user, sizeof (up->ut_user));
141 			user[sizeof (up->ut_user)] = '\0';
142 			strncpy(ttyn, up->ut_line, sizeof (up->ut_line));
143 			ttyn[sizeof (up->ut_line)] = '\0';
144 			strncpy(rhost, up->ut_host, sizeof (up->ut_host));
145 			rhost[sizeof (up->ut_host)] = '\0';
146 
147 			if (pam_start("ttymon", user, NULL, &pamh)
148 							== PAM_SUCCESS) {
149 				(void) pam_set_item(pamh, PAM_TTY, ttyn);
150 				(void) pam_set_item(pamh, PAM_RHOST, rhost);
151 				(void) pam_close_session(pamh, 0);
152 				(void) pam_end(pamh, PAM_SUCCESS);
153 			}
154 
155 
156 			up->ut_type = DEAD_PROCESS;
157 			up->ut_exit.e_termination = WTERMSIG(status);
158 			up->ut_exit.e_exit = WEXITSTATUS(status);
159 			(void) time(&up->ut_tv.tv_sec);
160 
161 			if (modutx(up) == NULL) {
162 				/*
163 				 * Since modutx failed we'll
164 				 * write out the new entry
165 				 * ourselves.
166 				 */
167 				(void) pututxline(up);
168 				updwtmpx("wtmpx", up);
169 			}
170 			break;
171 		}
172 	}
173 	endutxent();
174 }
175 
176 /*
177  * getty_account	- This is a copy of old getty account routine.
178  *			- This is only called if ttymon is invoked as getty.
179  *			- It tries to find its own INIT_PROCESS entry in utmpx
180  *			- and change it to LOGIN_PROCESS
181  */
182 void
183 getty_account(line)
184 char *line;
185 {
186 	pid_t ownpid;
187 	struct utmpx *u;
188 
189 	ownpid = getpid();
190 
191 	setutxent();
192 	while ((u = getutxent()) != NULL) {
193 
194 		if (u->ut_type == INIT_PROCESS && u->ut_pid == ownpid) {
195 			(void) strncpy(u->ut_line, lastname(line),
196 				sizeof (u->ut_line));
197 			(void) strncpy(u->ut_user, "LOGIN",
198 					sizeof (u->ut_user));
199 			u->ut_type = LOGIN_PROCESS;
200 
201 			/* Write out the updated entry. */
202 			(void) pututxline(u);
203 			break;
204 		}
205 	}
206 
207 	/* create wtmpx entry also */
208 	if (u != NULL)
209 		updwtmpx("/etc/wtmpx", u);
210 
211 	endutxent();
212 }
213