xref: /illumos-gate/usr/src/lib/libutempter/common/utempter.c (revision 8124b8119d8ab7f80f1bd8b094cd96356f531b54)
1*8124b811SYuri Pankov /*
2*8124b811SYuri Pankov  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3*8124b811SYuri Pankov  *
4*8124b811SYuri Pankov  * Copyright (c) 2009 Ed Schouten <ed@FreeBSD.org>
5*8124b811SYuri Pankov  * All rights reserved.
6*8124b811SYuri Pankov  *
7*8124b811SYuri Pankov  * Redistribution and use in source and binary forms, with or without
8*8124b811SYuri Pankov  * modification, are permitted provided that the following conditions
9*8124b811SYuri Pankov  * are met:
10*8124b811SYuri Pankov  * 1. Redistributions of source code must retain the above copyright
11*8124b811SYuri Pankov  *    notice, this list of conditions and the following disclaimer.
12*8124b811SYuri Pankov  * 2. Redistributions in binary form must reproduce the above copyright
13*8124b811SYuri Pankov  *    notice, this list of conditions and the following disclaimer in the
14*8124b811SYuri Pankov  *    documentation and/or other materials provided with the distribution.
15*8124b811SYuri Pankov  *
16*8124b811SYuri Pankov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*8124b811SYuri Pankov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*8124b811SYuri Pankov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*8124b811SYuri Pankov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*8124b811SYuri Pankov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*8124b811SYuri Pankov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*8124b811SYuri Pankov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*8124b811SYuri Pankov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*8124b811SYuri Pankov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*8124b811SYuri Pankov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8124b811SYuri Pankov  * SUCH DAMAGE.
27*8124b811SYuri Pankov  */
28*8124b811SYuri Pankov 
29*8124b811SYuri Pankov #include <sys/types.h>
30*8124b811SYuri Pankov 
31*8124b811SYuri Pankov #include <pwd.h>
32*8124b811SYuri Pankov #include <stdlib.h>
33*8124b811SYuri Pankov #include <string.h>
34*8124b811SYuri Pankov #include <unistd.h>
35*8124b811SYuri Pankov #include <utmpx.h>
36*8124b811SYuri Pankov 
37*8124b811SYuri Pankov static int last_fd = -1;
38*8124b811SYuri Pankov 
39*8124b811SYuri Pankov static void
utempter_update_utmpx(int type,int fd,const char * host)40*8124b811SYuri Pankov utempter_update_utmpx(int type, int fd, const char *host)
41*8124b811SYuri Pankov {
42*8124b811SYuri Pankov 	struct utmpx ut;
43*8124b811SYuri Pankov 	struct passwd *pw;
44*8124b811SYuri Pankov 	uid_t uid;
45*8124b811SYuri Pankov 
46*8124b811SYuri Pankov 	(void) memset(&ut, 0, sizeof (ut));
47*8124b811SYuri Pankov 	ut.ut_type = type;
48*8124b811SYuri Pankov 	ut.ut_pid = getpid();
49*8124b811SYuri Pankov 	ut.ut_session = getsid(0);
50*8124b811SYuri Pankov 	(void) gettimeofday(&ut.ut_tv, NULL);
51*8124b811SYuri Pankov 	if (snprintf(ut.ut_id, sizeof (ut.ut_id), "f%d", fd) >=
52*8124b811SYuri Pankov 	    sizeof (ut.ut_id))
53*8124b811SYuri Pankov 		return;
54*8124b811SYuri Pankov 	uid = getuid();
55*8124b811SYuri Pankov 	if ((pw = getpwuid(uid)) == NULL)
56*8124b811SYuri Pankov 		return;
57*8124b811SYuri Pankov 	(void) strlcpy(ut.ut_user, pw->pw_name, sizeof (ut.ut_user));
58*8124b811SYuri Pankov 
59*8124b811SYuri Pankov 	if (type == DEAD_PROCESS) {
60*8124b811SYuri Pankov 		struct utmpx *ut1;
61*8124b811SYuri Pankov 		struct utmpx ut2;
62*8124b811SYuri Pankov 
63*8124b811SYuri Pankov 		(void) memset(&ut2, 0, sizeof (ut2));
64*8124b811SYuri Pankov 		ut2.ut_type = USER_PROCESS;
65*8124b811SYuri Pankov 		if (snprintf(ut2.ut_id, sizeof (ut2.ut_id), "f%d", fd) >=
66*8124b811SYuri Pankov 		    sizeof (ut2.ut_id))
67*8124b811SYuri Pankov 			return;
68*8124b811SYuri Pankov 		if ((ut1 = getutxid(&ut2)) == NULL)
69*8124b811SYuri Pankov 			return;
70*8124b811SYuri Pankov 		(void) strlcpy(ut.ut_line, ut1->ut_line, sizeof (ut.ut_line));
71*8124b811SYuri Pankov 	} else {
72*8124b811SYuri Pankov 		char *line = ptsname(fd);
73*8124b811SYuri Pankov 		if (line == NULL)
74*8124b811SYuri Pankov 			return;
75*8124b811SYuri Pankov 		(void) strlcpy(ut.ut_line, line + strlen("/dev/"),
76*8124b811SYuri Pankov 		    sizeof (ut.ut_line));
77*8124b811SYuri Pankov 	}
78*8124b811SYuri Pankov 
79*8124b811SYuri Pankov 	if (host != NULL) {
80*8124b811SYuri Pankov 		(void) strlcpy(ut.ut_host, host, sizeof (ut.ut_host));
81*8124b811SYuri Pankov 		ut.ut_syslen = strlen(ut.ut_host) + 1;
82*8124b811SYuri Pankov 	}
83*8124b811SYuri Pankov 
84*8124b811SYuri Pankov 	setutxent();
85*8124b811SYuri Pankov 	(void) pututxline(&ut);
86*8124b811SYuri Pankov 	endutxent();
87*8124b811SYuri Pankov }
88*8124b811SYuri Pankov 
89*8124b811SYuri Pankov int
utempter_add_record(int fd,const char * host)90*8124b811SYuri Pankov utempter_add_record(int fd, const char *host)
91*8124b811SYuri Pankov {
92*8124b811SYuri Pankov 	utempter_update_utmpx(USER_PROCESS, fd, host);
93*8124b811SYuri Pankov 	last_fd = fd;
94*8124b811SYuri Pankov 	return (0);
95*8124b811SYuri Pankov }
96*8124b811SYuri Pankov 
97*8124b811SYuri Pankov int
utempter_remove_record(int fd)98*8124b811SYuri Pankov utempter_remove_record(int fd)
99*8124b811SYuri Pankov {
100*8124b811SYuri Pankov 	utempter_update_utmpx(DEAD_PROCESS, fd, NULL);
101*8124b811SYuri Pankov 	if (last_fd == fd)
102*8124b811SYuri Pankov 		last_fd = -1;
103*8124b811SYuri Pankov 	return (0);
104*8124b811SYuri Pankov }
105*8124b811SYuri Pankov 
106*8124b811SYuri Pankov int
utempter_remove_added_record(void)107*8124b811SYuri Pankov utempter_remove_added_record(void)
108*8124b811SYuri Pankov {
109*8124b811SYuri Pankov 	if (last_fd < 0)
110*8124b811SYuri Pankov 		return (0);
111*8124b811SYuri Pankov 	utempter_update_utmpx(DEAD_PROCESS, last_fd, NULL);
112*8124b811SYuri Pankov 	last_fd = -1;
113*8124b811SYuri Pankov 	return (0);
114*8124b811SYuri Pankov }
115*8124b811SYuri Pankov 
116*8124b811SYuri Pankov void
addToUtmp(const char * pty __unused,const char * host,int fd)117*8124b811SYuri Pankov addToUtmp(const char *pty __unused, const char *host, int fd)
118*8124b811SYuri Pankov {
119*8124b811SYuri Pankov 	(void) utempter_add_record(fd, host);
120*8124b811SYuri Pankov }
121*8124b811SYuri Pankov 
122*8124b811SYuri Pankov void
removeFromUtmp(void)123*8124b811SYuri Pankov removeFromUtmp(void)
124*8124b811SYuri Pankov {
125*8124b811SYuri Pankov 	(void) utempter_remove_added_record();
126*8124b811SYuri Pankov }
127*8124b811SYuri Pankov 
128*8124b811SYuri Pankov void
removeLineFromUtmp(const char * pty __unused,int fd)129*8124b811SYuri Pankov removeLineFromUtmp(const char *pty __unused, int fd)
130*8124b811SYuri Pankov {
131*8124b811SYuri Pankov 	(void) utempter_remove_record(fd);
132*8124b811SYuri Pankov }
133