File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / src / get_pty.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:13 2013 UTC (10 years, 11 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, v1_8_7p0, v1_8_7, v1_8_10p3_0, v1_8_10p3, HEAD
1.8.7

    1: /*
    2:  * Copyright (c) 2009-2012 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/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;
   65:     int rval = 0;
   66:     debug_decl(get_pty, SUDO_DEBUG_PTY)
   67: 
   68:     if ((gr = getgrnam("tty")) != NULL)
   69: 	ttygid = gr->gr_gid;
   70: 
   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);
   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;
   84:     int rval = 0;
   85:     debug_decl(get_pty, SUDO_DEBUG_PTY)
   86: 
   87:     /* IRIX-style dynamic ptys (may fork) */
   88:     line = _getpty(master, O_RDWR, S_IRUSR|S_IWUSR|S_IWGRP, 0);
   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: 	}
   99:     }
  100:     debug_return_bool(rval);
  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;
  122:     int rval = 0;
  123:     debug_decl(get_pty, SUDO_DEBUG_PTY)
  124: 
  125:     *master = posix_openpt(O_RDWR|O_NOCTTY);
  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: 	}
  142: # if defined(I_PUSH) && !defined(_AIX)
  143: 	ioctl(*slave, I_PUSH, "ptem");	/* pseudo tty emulation module */
  144: 	ioctl(*slave, I_PUSH, "ldterm");	/* line discipline module */
  145: # endif
  146: 	(void) chown(line, ttyuid, -1);
  147: 	strlcpy(name, line, namesz);
  148: 	rval = 1;
  149:     }
  150: done:
  151:     debug_return_bool(rval);
  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;
  164:     int rval = 0;
  165:     debug_decl(get_pty, SUDO_DEBUG_PTY)
  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)
  177: 		    goto done; /* out of ptys */
  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);
  189: 		    rval = 1; /* success */
  190: 		    goto done;
  191: 	    }
  192: 	    (void) close(*master);
  193: 	}
  194:     }
  195: done:
  196:     debug_return(rval);
  197: }
  198: #endif /* HAVE_OPENPTY */

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