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