Annotation of embedaddon/sudo/src/get_pty.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (c) 2009-2011 Todd C. Miller <Todd.Miller@courtesan.com>
! 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/param.h>
! 21: #include <sys/stat.h>
! 22: #include <sys/ioctl.h>
! 23: #ifdef HAVE_SYS_STROPTS_H
! 24: #include <sys/stropts.h>
! 25: #endif /* HAVE_SYS_STROPTS_H */
! 26: #include <stdio.h>
! 27: #ifdef STDC_HEADERS
! 28: # include <stdlib.h>
! 29: # include <stddef.h>
! 30: #else
! 31: # ifdef HAVE_STDLIB_H
! 32: # include <stdlib.h>
! 33: # endif
! 34: #endif /* STDC_HEADERS */
! 35: #ifdef HAVE_STRING_H
! 36: # include <string.h>
! 37: #endif /* HAVE_STRING_H */
! 38: #ifdef HAVE_STRINGS_H
! 39: # include <strings.h>
! 40: #endif /* HAVE_STRINGS_H */
! 41: #ifdef HAVE_UNISTD_H
! 42: # include <unistd.h>
! 43: #endif /* HAVE_UNISTD_H */
! 44: #include <errno.h>
! 45: #include <fcntl.h>
! 46: #include <grp.h>
! 47: #include <pwd.h>
! 48:
! 49: #if defined(HAVE_LIBUTIL_H)
! 50: # include <libutil.h>
! 51: #elif defined(HAVE_UTIL_H)
! 52: # include <util.h>
! 53: #endif
! 54: #ifdef HAVE_PTY_H
! 55: # include <pty.h>
! 56: #endif
! 57:
! 58: #include "sudo.h"
! 59:
! 60: #if defined(HAVE_OPENPTY)
! 61: int
! 62: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
! 63: {
! 64: struct group *gr;
! 65: gid_t ttygid = -1;
! 66:
! 67: if ((gr = getgrnam("tty")) != NULL)
! 68: ttygid = gr->gr_gid;
! 69:
! 70: if (openpty(master, slave, name, NULL, NULL) != 0)
! 71: return 0;
! 72: if (chown(name, ttyuid, ttygid) != 0)
! 73: return 0;
! 74: return 1;
! 75: }
! 76:
! 77: #elif defined(HAVE__GETPTY)
! 78: int
! 79: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
! 80: {
! 81: char *line;
! 82:
! 83: /* IRIX-style dynamic ptys (may fork) */
! 84: line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
! 85: if (line == NULL)
! 86: return 0;
! 87: *slave = open(line, O_RDWR|O_NOCTTY, 0);
! 88: if (*slave == -1) {
! 89: close(*master);
! 90: return 0;
! 91: }
! 92: (void) chown(line, ttyuid, -1);
! 93: strlcpy(name, line, namesz);
! 94: return 1;
! 95: }
! 96: #elif defined(HAVE_GRANTPT)
! 97: # ifndef HAVE_POSIX_OPENPT
! 98: static int
! 99: posix_openpt(int oflag)
! 100: {
! 101: int fd;
! 102:
! 103: # ifdef _AIX
! 104: fd = open("/dev/ptc", oflag);
! 105: # else
! 106: fd = open("/dev/ptmx", oflag);
! 107: # endif
! 108: return fd;
! 109: }
! 110: # endif /* HAVE_POSIX_OPENPT */
! 111:
! 112: int
! 113: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
! 114: {
! 115: char *line;
! 116:
! 117: *master = posix_openpt(O_RDWR|O_NOCTTY);
! 118: if (*master == -1)
! 119: return 0;
! 120:
! 121: (void) grantpt(*master); /* may fork */
! 122: if (unlockpt(*master) != 0) {
! 123: close(*master);
! 124: return 0;
! 125: }
! 126: line = ptsname(*master);
! 127: if (line == NULL) {
! 128: close(*master);
! 129: return 0;
! 130: }
! 131: *slave = open(line, O_RDWR|O_NOCTTY, 0);
! 132: if (*slave == -1) {
! 133: close(*master);
! 134: return 0;
! 135: }
! 136: # if defined(I_PUSH) && !defined(_AIX)
! 137: ioctl(*slave, I_PUSH, "ptem"); /* pseudo tty emulation module */
! 138: ioctl(*slave, I_PUSH, "ldterm"); /* line discipline module */
! 139: # endif
! 140: (void) chown(line, ttyuid, -1);
! 141: strlcpy(name, line, namesz);
! 142: return 1;
! 143: }
! 144:
! 145: #else /* Old-style BSD ptys */
! 146:
! 147: static char line[] = "/dev/ptyXX";
! 148:
! 149: int
! 150: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
! 151: {
! 152: char *bank, *cp;
! 153: struct group *gr;
! 154: gid_t ttygid = -1;
! 155:
! 156: if ((gr = getgrnam("tty")) != NULL)
! 157: ttygid = gr->gr_gid;
! 158:
! 159: for (bank = "pqrs"; *bank != '\0'; bank++) {
! 160: line[sizeof("/dev/ptyX") - 2] = *bank;
! 161: for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
! 162: line[sizeof("/dev/ptyXX") - 2] = *cp;
! 163: *master = open(line, O_RDWR|O_NOCTTY, 0);
! 164: if (*master == -1) {
! 165: if (errno == ENOENT)
! 166: return 0; /* out of ptys */
! 167: continue; /* already in use */
! 168: }
! 169: line[sizeof("/dev/p") - 2] = 't';
! 170: (void) chown(line, ttyuid, ttygid);
! 171: (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
! 172: # ifdef HAVE_REVOKE
! 173: (void) revoke(line);
! 174: # endif
! 175: *slave = open(line, O_RDWR|O_NOCTTY, 0);
! 176: if (*slave != -1) {
! 177: strlcpy(name, line, namesz);
! 178: return 1; /* success */
! 179: }
! 180: (void) close(*master);
! 181: }
! 182: }
! 183: return 0;
! 184: }
! 185: #endif /* HAVE_OPENPTY */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>