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