xref: /onnv-gate/usr/src/cmd/ttymon/tmutmp.c (revision 5091:7a81097e277f)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*5091Sas145665  * Common Development and Distribution License (the "License").
6*5091Sas145665  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*5091Sas145665  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
270Sstevel@tonic-gate /*	  All Rights Reserved  	*/
280Sstevel@tonic-gate 
290Sstevel@tonic-gate /*
300Sstevel@tonic-gate  * University Copyright- Copyright (c) 1982, 1986, 1988
310Sstevel@tonic-gate  * The Regents of the University of California
320Sstevel@tonic-gate  * All Rights Reserved
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  * University Acknowledgment- Portions of this document are derived from
350Sstevel@tonic-gate  * software developed by the University of California, Berkeley, and its
360Sstevel@tonic-gate  * contributors.
370Sstevel@tonic-gate  */
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
400Sstevel@tonic-gate 
410Sstevel@tonic-gate #include	<unistd.h>
420Sstevel@tonic-gate #include	<stdlib.h>
430Sstevel@tonic-gate #include	<stdio.h>
440Sstevel@tonic-gate #include	<fcntl.h>
450Sstevel@tonic-gate #include	<sys/types.h>
460Sstevel@tonic-gate #include	<sys/wait.h>
470Sstevel@tonic-gate #include	<string.h>
480Sstevel@tonic-gate #include	<memory.h>
490Sstevel@tonic-gate #include	<utmpx.h>
500Sstevel@tonic-gate #include	<security/pam_appl.h>
510Sstevel@tonic-gate 
520Sstevel@tonic-gate #include	"sac.h"
530Sstevel@tonic-gate #include	"tmextern.h"
540Sstevel@tonic-gate 
550Sstevel@tonic-gate extern	char	*lastname();
560Sstevel@tonic-gate 
570Sstevel@tonic-gate /*
580Sstevel@tonic-gate  * account - create a utmpx record for service
590Sstevel@tonic-gate  *
600Sstevel@tonic-gate  */
610Sstevel@tonic-gate 
620Sstevel@tonic-gate int
account(line)630Sstevel@tonic-gate account(line)
640Sstevel@tonic-gate char	*line;
650Sstevel@tonic-gate {
660Sstevel@tonic-gate 	struct utmpx utmpx;			/* prototype utmpx entry */
670Sstevel@tonic-gate 	struct utmpx *up = &utmpx;		/* and a pointer to it */
680Sstevel@tonic-gate 
690Sstevel@tonic-gate 	(void) memset(up, '\0', sizeof (utmpx));
700Sstevel@tonic-gate 	up->ut_user[0] = '.';
710Sstevel@tonic-gate 	(void) strncpy(&up->ut_user[1], Tag, sizeof (up->ut_user)-1);
720Sstevel@tonic-gate 	(void) strncpy(up->ut_line, lastname(line), sizeof (up->ut_line));
730Sstevel@tonic-gate 	up->ut_pid = getpid();
740Sstevel@tonic-gate 	up->ut_type = USER_PROCESS;
750Sstevel@tonic-gate 	up->ut_id[0] = 't';
760Sstevel@tonic-gate 	up->ut_id[1] = 'm';
770Sstevel@tonic-gate 	up->ut_id[2] = SC_WILDC;
780Sstevel@tonic-gate 	up->ut_id[3] = SC_WILDC;
790Sstevel@tonic-gate 	up->ut_exit.e_termination = 0;
800Sstevel@tonic-gate 	up->ut_exit.e_exit = 0;
810Sstevel@tonic-gate 	(void) time(&up->ut_tv.tv_sec);
820Sstevel@tonic-gate 	if (makeutx(up) == NULL) {
830Sstevel@tonic-gate 		log("makeutx for pid %d failed", up->ut_pid);
840Sstevel@tonic-gate 		return (-1);
850Sstevel@tonic-gate 	}
860Sstevel@tonic-gate 	return (0);
870Sstevel@tonic-gate }
880Sstevel@tonic-gate 
890Sstevel@tonic-gate /*
900Sstevel@tonic-gate  * checkut_line	- check if a login is active on the requested device
910Sstevel@tonic-gate  */
920Sstevel@tonic-gate int
checkut_line(char * line)930Sstevel@tonic-gate checkut_line(char *line)
940Sstevel@tonic-gate {
950Sstevel@tonic-gate 	struct utmpx *u;
960Sstevel@tonic-gate 	char buf[33], ttyn[33];
970Sstevel@tonic-gate 	int rvalue = 0;
98*5091Sas145665 	pid_t ownpid = getpid();
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	(void) strncpy(buf, lastname(line), sizeof (u->ut_line));
1010Sstevel@tonic-gate 	buf[sizeof (u->ut_line)] = '\0';
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	setutxent();
1040Sstevel@tonic-gate 	while ((u = getutxent()) != NULL) {
105*5091Sas145665 		if (u->ut_pid == ownpid) {
106*5091Sas145665 			if (u->ut_type == USER_PROCESS) {
107*5091Sas145665 				strncpy(ttyn, u->ut_line, sizeof (u->ut_line));
108*5091Sas145665 				ttyn[sizeof (u->ut_line)] = '\0';
109*5091Sas145665 				if (strcmp(buf, ttyn) == 0) {
110*5091Sas145665 					rvalue = 1;
111*5091Sas145665 					break;
112*5091Sas145665 				}
1130Sstevel@tonic-gate 			}
1140Sstevel@tonic-gate 		}
1150Sstevel@tonic-gate 	}
1160Sstevel@tonic-gate 	endutxent();
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 	return (rvalue);
1190Sstevel@tonic-gate }
1200Sstevel@tonic-gate 
1210Sstevel@tonic-gate 
1220Sstevel@tonic-gate void
cleanut(pid,status)1230Sstevel@tonic-gate cleanut(pid, status)
1240Sstevel@tonic-gate 	pid_t	pid;
1250Sstevel@tonic-gate 	int	status;
1260Sstevel@tonic-gate {
1270Sstevel@tonic-gate 	pam_handle_t *pamh;
1280Sstevel@tonic-gate 	struct utmpx *up;
1290Sstevel@tonic-gate 	struct utmpx ut;
1300Sstevel@tonic-gate 	char user[33], ttyn[33], rhost[258];
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	setutxent();
1330Sstevel@tonic-gate 	while (up = getutxent()) {
1340Sstevel@tonic-gate 		if (up->ut_pid == pid) {
1350Sstevel@tonic-gate 			if (up->ut_type == DEAD_PROCESS) {
1360Sstevel@tonic-gate 				/* Cleaned up elsewhere. */
1370Sstevel@tonic-gate 				break;
1380Sstevel@tonic-gate 			}
1390Sstevel@tonic-gate 
1400Sstevel@tonic-gate 			strncpy(user, up->ut_user, sizeof (up->ut_user));
1410Sstevel@tonic-gate 			user[sizeof (up->ut_user)] = '\0';
1420Sstevel@tonic-gate 			strncpy(ttyn, up->ut_line, sizeof (up->ut_line));
1430Sstevel@tonic-gate 			ttyn[sizeof (up->ut_line)] = '\0';
1440Sstevel@tonic-gate 			strncpy(rhost, up->ut_host, sizeof (up->ut_host));
1450Sstevel@tonic-gate 			rhost[sizeof (up->ut_host)] = '\0';
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 			if (pam_start("ttymon", user, NULL, &pamh)
1480Sstevel@tonic-gate 							== PAM_SUCCESS) {
1490Sstevel@tonic-gate 				(void) pam_set_item(pamh, PAM_TTY, ttyn);
1500Sstevel@tonic-gate 				(void) pam_set_item(pamh, PAM_RHOST, rhost);
1510Sstevel@tonic-gate 				(void) pam_close_session(pamh, 0);
1520Sstevel@tonic-gate 				(void) pam_end(pamh, PAM_SUCCESS);
1530Sstevel@tonic-gate 			}
1540Sstevel@tonic-gate 
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 			up->ut_type = DEAD_PROCESS;
1570Sstevel@tonic-gate 			up->ut_exit.e_termination = WTERMSIG(status);
1580Sstevel@tonic-gate 			up->ut_exit.e_exit = WEXITSTATUS(status);
1590Sstevel@tonic-gate 			(void) time(&up->ut_tv.tv_sec);
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 			if (modutx(up) == NULL) {
1620Sstevel@tonic-gate 				/*
1630Sstevel@tonic-gate 				 * Since modutx failed we'll
1640Sstevel@tonic-gate 				 * write out the new entry
1650Sstevel@tonic-gate 				 * ourselves.
1660Sstevel@tonic-gate 				 */
1670Sstevel@tonic-gate 				(void) pututxline(up);
1680Sstevel@tonic-gate 				updwtmpx("wtmpx", up);
1690Sstevel@tonic-gate 			}
1700Sstevel@tonic-gate 			break;
1710Sstevel@tonic-gate 		}
1720Sstevel@tonic-gate 	}
1730Sstevel@tonic-gate 	endutxent();
1740Sstevel@tonic-gate }
1750Sstevel@tonic-gate 
1760Sstevel@tonic-gate /*
1770Sstevel@tonic-gate  * getty_account	- This is a copy of old getty account routine.
1780Sstevel@tonic-gate  *			- This is only called if ttymon is invoked as getty.
1790Sstevel@tonic-gate  *			- It tries to find its own INIT_PROCESS entry in utmpx
1800Sstevel@tonic-gate  *			- and change it to LOGIN_PROCESS
1810Sstevel@tonic-gate  */
1820Sstevel@tonic-gate void
getty_account(line)1830Sstevel@tonic-gate getty_account(line)
1840Sstevel@tonic-gate char *line;
1850Sstevel@tonic-gate {
1860Sstevel@tonic-gate 	pid_t ownpid;
1870Sstevel@tonic-gate 	struct utmpx *u;
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 	ownpid = getpid();
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate 	setutxent();
1920Sstevel@tonic-gate 	while ((u = getutxent()) != NULL) {
1930Sstevel@tonic-gate 
1940Sstevel@tonic-gate 		if (u->ut_type == INIT_PROCESS && u->ut_pid == ownpid) {
1950Sstevel@tonic-gate 			(void) strncpy(u->ut_line, lastname(line),
1960Sstevel@tonic-gate 				sizeof (u->ut_line));
1970Sstevel@tonic-gate 			(void) strncpy(u->ut_user, "LOGIN",
1980Sstevel@tonic-gate 					sizeof (u->ut_user));
1990Sstevel@tonic-gate 			u->ut_type = LOGIN_PROCESS;
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 			/* Write out the updated entry. */
2020Sstevel@tonic-gate 			(void) pututxline(u);
2030Sstevel@tonic-gate 			break;
2040Sstevel@tonic-gate 		}
2050Sstevel@tonic-gate 	}
2060Sstevel@tonic-gate 
2070Sstevel@tonic-gate 	/* create wtmpx entry also */
2080Sstevel@tonic-gate 	if (u != NULL)
2090Sstevel@tonic-gate 		updwtmpx("/etc/wtmpx", u);
2100Sstevel@tonic-gate 
2110Sstevel@tonic-gate 	endutxent();
2120Sstevel@tonic-gate }
213