File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / src / get_pty.c
Revision 1.1: download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 16:23:02 2012 UTC (12 years, 4 months ago) by misho
CVS tags: MAIN, HEAD
Initial revision

    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>