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>