Annotation of embedaddon/sudo/src/get_pty.c, revision 1.1.1.2

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;
1.1.1.2 ! misho      66:     int rval = 0;
        !            67:     debug_decl(get_pty, SUDO_DEBUG_PTY)
1.1       misho      68: 
                     69:     if ((gr = getgrnam("tty")) != NULL)
                     70:        ttygid = gr->gr_gid;
                     71: 
1.1.1.2 ! misho      72:     if (openpty(master, slave, name, NULL, NULL) == 0) {
        !            73:        if (chown(name, ttyuid, ttygid) == 0)
        !            74:            rval = 1;
        !            75:     }
        !            76: 
        !            77:     debug_return_bool(rval);
1.1       misho      78: }
                     79: 
                     80: #elif defined(HAVE__GETPTY)
                     81: int
                     82: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
                     83: {
                     84:     char *line;
1.1.1.2 ! misho      85:     int rval = 0;
        !            86:     debug_decl(get_pty, SUDO_DEBUG_PTY)
1.1       misho      87: 
                     88:     /* IRIX-style dynamic ptys (may fork) */
                     89:     line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
1.1.1.2 ! misho      90:     if (line != NULL) {
        !            91:        *slave = open(line, O_RDWR|O_NOCTTY, 0);
        !            92:        if (*slave != -1) {
        !            93:            (void) chown(line, ttyuid, -1);
        !            94:            strlcpy(name, line, namesz);
        !            95:            rval = 1;
        !            96:        } else {
        !            97:            close(*master);
        !            98:            *master = -1;
        !            99:        }
1.1       misho     100:     }
1.1.1.2 ! misho     101:     debug_return_bool(rval);
1.1       misho     102: }
                    103: #elif defined(HAVE_GRANTPT)
                    104: # ifndef HAVE_POSIX_OPENPT
                    105: static int
                    106: posix_openpt(int oflag)
                    107: {
                    108:     int fd;
                    109: 
                    110: #  ifdef _AIX
                    111:     fd = open("/dev/ptc", oflag);
                    112: #  else
                    113:     fd = open("/dev/ptmx", oflag);
                    114: #  endif
                    115:     return fd;
                    116: }
                    117: # endif /* HAVE_POSIX_OPENPT */
                    118: 
                    119: int
                    120: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
                    121: {
                    122:     char *line;
1.1.1.2 ! misho     123:     int rval = 0;
        !           124:     debug_decl(get_pty, SUDO_DEBUG_PTY)
1.1       misho     125: 
                    126:     *master = posix_openpt(O_RDWR|O_NOCTTY);
1.1.1.2 ! misho     127:     if (*master != -1) {
        !           128:        (void) grantpt(*master); /* may fork */
        !           129:        if (unlockpt(*master) != 0) {
        !           130:            close(*master);
        !           131:            goto done;
        !           132:        }
        !           133:        line = ptsname(*master);
        !           134:        if (line == NULL) {
        !           135:            close(*master);
        !           136:            goto done;
        !           137:        }
        !           138:        *slave = open(line, O_RDWR|O_NOCTTY, 0);
        !           139:        if (*slave == -1) {
        !           140:            close(*master);
        !           141:            goto done;
        !           142:        }
1.1       misho     143: # if defined(I_PUSH) && !defined(_AIX)
1.1.1.2 ! misho     144:        ioctl(*slave, I_PUSH, "ptem");  /* pseudo tty emulation module */
        !           145:        ioctl(*slave, I_PUSH, "ldterm");        /* line discipline module */
1.1       misho     146: # endif
1.1.1.2 ! misho     147:        (void) chown(line, ttyuid, -1);
        !           148:        strlcpy(name, line, namesz);
        !           149:        rval = 1;
        !           150:     }
        !           151: done:
        !           152:     debug_return_bool(rval);
1.1       misho     153: }
                    154: 
                    155: #else /* Old-style BSD ptys */
                    156: 
                    157: static char line[] = "/dev/ptyXX";
                    158: 
                    159: int
                    160: get_pty(int *master, int *slave, char *name, size_t namesz, uid_t ttyuid)
                    161: {
                    162:     char *bank, *cp;
                    163:     struct group *gr;
                    164:     gid_t ttygid = -1;
1.1.1.2 ! misho     165:     int rval = 0;
        !           166:     debug_decl(get_pty, SUDO_DEBUG_PTY)
1.1       misho     167: 
                    168:     if ((gr = getgrnam("tty")) != NULL)
                    169:        ttygid = gr->gr_gid;
                    170: 
                    171:     for (bank = "pqrs"; *bank != '\0'; bank++) {
                    172:        line[sizeof("/dev/ptyX") - 2] = *bank;
                    173:        for (cp = "0123456789abcdef"; *cp != '\0'; cp++) {
                    174:            line[sizeof("/dev/ptyXX") - 2] = *cp;
                    175:            *master = open(line, O_RDWR|O_NOCTTY, 0);
                    176:            if (*master == -1) {
                    177:                if (errno == ENOENT)
1.1.1.2 ! misho     178:                    goto done; /* out of ptys */
1.1       misho     179:                continue; /* already in use */
                    180:            }
                    181:            line[sizeof("/dev/p") - 2] = 't';
                    182:            (void) chown(line, ttyuid, ttygid);
                    183:            (void) chmod(line, S_IRUSR|S_IWUSR|S_IWGRP);
                    184: # ifdef HAVE_REVOKE
                    185:            (void) revoke(line);
                    186: # endif
                    187:            *slave = open(line, O_RDWR|O_NOCTTY, 0);
                    188:            if (*slave != -1) {
                    189:                    strlcpy(name, line, namesz);
1.1.1.2 ! misho     190:                    rval = 1; /* success */
        !           191:                    goto done;
1.1       misho     192:            }
                    193:            (void) close(*master);
                    194:        }
                    195:     }
1.1.1.2 ! misho     196: done:
        !           197:     debug_return(rval);
1.1       misho     198: }
                    199: #endif /* HAVE_OPENPTY */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>