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