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