Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sudo-project
GitHub Repository: sudo-project/sudo
Path: blob/main/src/get_pty.c
1532 views
1
/*
2
* SPDX-License-Identifier: ISC
3
*
4
* Copyright (c) 2009-2012, 2014-2016
5
* Todd C. Miller <[email protected]>
6
*
7
* Permission to use, copy, modify, and distribute this software for any
8
* purpose with or without fee is hereby granted, provided that the above
9
* copyright notice and this permission notice appear in all copies.
10
*
11
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18
*/
19
20
#include <config.h>
21
22
#include <sys/stat.h>
23
#include <sys/ioctl.h>
24
#ifdef HAVE_SYS_STROPTS_H
25
#include <sys/stropts.h>
26
#endif /* HAVE_SYS_STROPTS_H */
27
#include <stdlib.h>
28
#include <string.h>
29
#include <unistd.h>
30
#include <errno.h>
31
#include <fcntl.h>
32
#include <grp.h>
33
34
#if defined(HAVE_OPENPTY)
35
# if defined(HAVE_LIBUTIL_H)
36
# include <libutil.h> /* *BSD */
37
# elif defined(HAVE_UTIL_H)
38
# include <util.h> /* macOS */
39
# elif defined(HAVE_PTY_H)
40
# include <pty.h> /* Linux */
41
# else
42
# include <termios.h> /* Solaris */
43
# endif
44
#endif
45
46
#include <sudo.h>
47
48
#if defined(HAVE_OPENPTY)
49
char *
50
get_pty(int *leader, int *follower, uid_t ttyuid)
51
{
52
struct group *gr;
53
gid_t ttygid = (gid_t)-1;
54
char name[PATH_MAX];
55
char *ret = NULL;
56
debug_decl(get_pty, SUDO_DEBUG_PTY);
57
58
if ((gr = getgrnam("tty")) != NULL)
59
ttygid = gr->gr_gid;
60
61
if (openpty(leader, follower, name, NULL, NULL) == 0) {
62
if (chown(name, ttyuid, ttygid) == 0)
63
ret = strdup(name);
64
}
65
66
debug_return_str(ret);
67
}
68
69
#elif defined(HAVE__GETPTY)
70
char *
71
get_pty(int *leader, int *follower, uid_t ttyuid)
72
{
73
char *line;
74
char *ret = NULL;
75
debug_decl(get_pty, SUDO_DEBUG_PTY);
76
77
/* IRIX-style dynamic ptys (may fork) */
78
line = _getpty(leader, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
79
if (line != NULL) {
80
*follower = open(line, O_RDWR|O_NOCTTY, 0);
81
if (*follower != -1) {
82
(void) chown(line, ttyuid, -1);
83
ret = strdup(line);
84
} else {
85
close(*leader);
86
*leader = -1;
87
}
88
}
89
debug_return_str(ret);
90
}
91
#elif defined(HAVE_GRANTPT)
92
# ifndef HAVE_POSIX_OPENPT
93
static int
94
posix_openpt(int oflag)
95
{
96
int fd;
97
98
# ifdef _AIX
99
fd = open(_PATH_DEV "ptc", oflag);
100
# else
101
fd = open(_PATH_DEV "ptmx", oflag);
102
# endif
103
return fd;
104
}
105
# endif /* HAVE_POSIX_OPENPT */
106
107
char *
108
get_pty(int *leader, int *follower, uid_t ttyuid)
109
{
110
char *line, *ret = NULL;
111
debug_decl(get_pty, SUDO_DEBUG_PTY);
112
113
*leader = posix_openpt(O_RDWR|O_NOCTTY);
114
if (*leader != -1) {
115
(void) grantpt(*leader); /* may fork */
116
if (unlockpt(*leader) != 0) {
117
close(*leader);
118
goto done;
119
}
120
line = ptsname(*leader);
121
if (line == NULL) {
122
close(*leader);
123
goto done;
124
}
125
*follower = open(line, O_RDWR|O_NOCTTY, 0);
126
if (*follower == -1) {
127
close(*leader);
128
goto done;
129
}
130
# if defined(I_PUSH) && !defined(_AIX)
131
ioctl(*follower, I_PUSH, "ptem"); /* pseudo tty emulation module */
132
ioctl(*follower, I_PUSH, "ldterm"); /* line discipline module */
133
# endif
134
(void) chown(line, ttyuid, -1);
135
ret = strdup(line);
136
}
137
done:
138
debug_return_str(ret);
139
}
140
141
#else /* Old-style BSD ptys */
142
143
static char line[] = _PATH_DEV "ptyXX";
144
145
char *
146
get_pty(int *leader, int *follower, uid_t ttyuid)
147
{
148
char *bank, *cp;
149
struct group *gr;
150
gid_t ttygid = -1;
151
char *ret = NULL;
152
debug_decl(get_pty, SUDO_DEBUG_PTY);
153
154
if ((gr = getgrnam("tty")) != NULL)
155
ttygid = gr->gr_gid;
156
157
for (bank = "pqrs"; *bank != '\0'; bank++) {
158
line[sizeof(_PATH_DEV "ptyX") - 2] = *bank;
159
for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
160
line[sizeof(_PATH_DEV "ptyXX") - 2] = *cp;
161
*leader = open(line, O_RDWR|O_NOCTTY, 0);
162
if (*leader == -1) {
163
if (errno == ENOENT)
164
goto done; /* out of ptys */
165
continue; /* already in use */
166
}
167
line[sizeof(_PATH_DEV "p") - 2] = 't';
168
(void) chown(line, ttyuid, ttygid);
169
(void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
170
# ifdef HAVE_REVOKE
171
(void) revoke(line);
172
# endif
173
*follower = open(line, O_RDWR|O_NOCTTY, 0);
174
if (*follower != -1) {
175
ret = strdup(line);
176
goto done;
177
}
178
(void) close(*leader);
179
}
180
}
181
done:
182
debug_return_str(ret);
183
}
184
#endif /* HAVE_OPENPTY */
185
186