Annotation of embedaddon/sudo/src/get_pty.c, revision 1.1.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>