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 #include <unistd.h> 40 #include <stdlib.h> 41 #include <stdio.h> 42 #include <fcntl.h> 43 #include <sys/types.h> 44 #include <sys/wait.h> 45 #include <string.h> 46 #include <memory.h> 47 #include <utmpx.h> 48 #include <security/pam_appl.h> 49 50 #include "sac.h" 51 #include "tmextern.h" 52 53 /* 54 * account - create a utmpx record for service 55 * 56 */ 57 58 int 59 account(char *line) 60 { 61 struct utmpx utmpx; /* prototype utmpx entry */ 62 struct utmpx *up = &utmpx; /* and a pointer to it */ 63 64 (void) memset(up, '\0', sizeof (utmpx)); 65 up->ut_user[0] = '.'; 66 (void) strncpy(&up->ut_user[1], Tag, sizeof (up->ut_user)-1); 67 (void) strncpy(up->ut_line, lastname(line), sizeof (up->ut_line)); 68 up->ut_pid = getpid(); 69 up->ut_type = USER_PROCESS; 70 up->ut_id[0] = 't'; 71 up->ut_id[1] = 'm'; 72 up->ut_id[2] = SC_WILDC; 73 up->ut_id[3] = SC_WILDC; 74 up->ut_exit.e_termination = 0; 75 up->ut_exit.e_exit = 0; 76 (void) time(&up->ut_tv.tv_sec); 77 if (makeutx(up) == NULL) { 78 log("makeutx for pid %d failed", up->ut_pid); 79 return (-1); 80 } 81 return (0); 82 } 83 84 /* 85 * checkut_line - check if a login is active on the requested device 86 */ 87 int 88 checkut_line(char *line) 89 { 90 struct utmpx *u; 91 char buf[33], ttyn[33]; 92 int rvalue = 0; 93 pid_t ownpid = getpid(); 94 95 (void) strncpy(buf, lastname(line), sizeof (u->ut_line)); 96 buf[sizeof (u->ut_line)] = '\0'; 97 98 setutxent(); 99 while ((u = getutxent()) != NULL) { 100 if (u->ut_pid == ownpid) { 101 if (u->ut_type == USER_PROCESS) { 102 (void) strncpy(ttyn, u->ut_line, 103 sizeof (u->ut_line)); 104 ttyn[sizeof (u->ut_line)] = '\0'; 105 if (strcmp(buf, ttyn) == 0) { 106 rvalue = 1; 107 break; 108 } 109 } 110 } 111 } 112 endutxent(); 113 114 return (rvalue); 115 } 116 117 118 void 119 cleanut(pid_t pid, int status) 120 { 121 pam_handle_t *pamh; 122 struct utmpx *up; 123 char user[33], ttyn[33], rhost[258]; 124 125 setutxent(); 126 while ((up = getutxent())) { 127 if (up->ut_pid == pid) { 128 if (up->ut_type == DEAD_PROCESS) { 129 /* Cleaned up elsewhere. */ 130 break; 131 } 132 133 (void) strncpy(user, up->ut_user, sizeof (up->ut_user)); 134 user[sizeof (up->ut_user)] = '\0'; 135 (void) strncpy(ttyn, up->ut_line, sizeof (up->ut_line)); 136 ttyn[sizeof (up->ut_line)] = '\0'; 137 (void) strncpy(rhost, up->ut_host, 138 sizeof (up->ut_host)); 139 rhost[sizeof (up->ut_host)] = '\0'; 140 141 if (pam_start("ttymon", user, NULL, &pamh) == 142 PAM_SUCCESS) { 143 (void) pam_set_item(pamh, PAM_TTY, ttyn); 144 (void) pam_set_item(pamh, PAM_RHOST, rhost); 145 (void) pam_close_session(pamh, 0); 146 (void) pam_end(pamh, PAM_SUCCESS); 147 } 148 149 150 up->ut_type = DEAD_PROCESS; 151 up->ut_exit.e_termination = WTERMSIG(status); 152 up->ut_exit.e_exit = WEXITSTATUS(status); 153 (void) time(&up->ut_tv.tv_sec); 154 155 if (modutx(up) == NULL) { 156 /* 157 * Since modutx failed we'll 158 * write out the new entry 159 * ourselves. 160 */ 161 (void) pututxline(up); 162 updwtmpx("wtmpx", up); 163 } 164 break; 165 } 166 } 167 endutxent(); 168 } 169 170 /* 171 * getty_account - This is a copy of old getty account routine. 172 * - This is only called if ttymon is invoked as getty. 173 * - It tries to find its own INIT_PROCESS entry in utmpx 174 * - and change it to LOGIN_PROCESS 175 */ 176 void 177 getty_account(char *line) 178 { 179 pid_t ownpid; 180 struct utmpx *u; 181 182 ownpid = getpid(); 183 184 setutxent(); 185 while ((u = getutxent()) != NULL) { 186 187 if (u->ut_type == INIT_PROCESS && u->ut_pid == ownpid) { 188 (void) strncpy(u->ut_line, lastname(line), 189 sizeof (u->ut_line)); 190 (void) strncpy(u->ut_user, "LOGIN", 191 sizeof (u->ut_user)); 192 u->ut_type = LOGIN_PROCESS; 193 194 /* Write out the updated entry. */ 195 (void) pututxline(u); 196 break; 197 } 198 } 199 200 /* create wtmpx entry also */ 201 if (u != NULL) 202 updwtmpx("/etc/wtmpx", u); 203 204 endutxent(); 205 } 206