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