Index: kgrantpty.c =================================================================== RCS file: /home/kde/kdelibs/kdecore/kgrantpty.c,v retrieving revision 1.13 diff -U2 -r1.13 kgrantpty.c --- kgrantpty.c 20 Nov 2003 15:53:10 -0000 1.13 +++ kgrantpty.c 13 Jan 2004 17:36:44 -0000 @@ -25,6 +25,7 @@ */ +#include + #include -#include /* for BSD */ #include #include @@ -46,5 +47,4 @@ int main (int argc, char *argv[]) { - char* pty; struct stat st; struct group* p; @@ -72,84 +72,68 @@ } - /* setup parameters for the operation ***********************************/ - - if (!strcmp(argv[1],"--grant")) - { - uid = getuid(); /* current user id */ - mod = S_IRUSR | S_IWUSR | S_IWGRP; - } - else - { - uid = 0; /* root */ - mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; - } - /* Get the group ID of the special `tty' group. */ - p = getgrnam(TTY_GROUP); /* posix */ - gid = p ? p->gr_gid : getgid (); /* posix */ fd = atoi(argv[2]); - /* get slave pty name from master pty file handle in PTY_FILENO *********/ - - /* Check that fd is a valid master pseudo terminal. */ - pty = ttyname(fd); /* posix */ - -#if defined(BSD_PTY_HACK) - if (pty == NULL) + /* get slave pty name from master pty file handle *********/ +#ifdef HAVE_PTSNAME + tty = ptsname(fd); + if (!tty) +#endif { - /* - Hack to make kgrantpty work on some versions of FreeBSD (and possibly - other systems): ttyname(3) does not work with a file descriptor opened - on a /dev/pty?? device. - - Instead, this code looks through all the devices in /dev for a device - which has the same inode as our PTY_FILENO descriptor... if found, we - have the name for our pty. - */ - - struct dirent *dirp; - DIR *dp; - struct stat dsb; - - if (uid == 0) { - p = getgrnam("wheel"); - gid = p ? p->gr_gid : getgid(); - } + /* Check that fd is a valid master pseudo terminal. */ + char *pty = ttyname(fd); - if (fstat(fd, &dsb) != -1) { - if ((dp = opendir(_PATH_DEV)) != NULL) { - while ((dirp = readdir(dp))) { - if (dirp->d_fileno != dsb.st_ino) - continue; - pty = malloc(sizeof(_PATH_DEV) + strlen(dirp->d_name)); - if (pty) { - strcpy(pty, _PATH_DEV); - strcat(pty, dirp->d_name); +#ifdef BSD_PTY_HACK + if (pty == NULL) + { + /* + Hack to make kgrantpty work on some versions of FreeBSD (and possibly + other systems): ttyname(3) does not work with a file descriptor opened + on a /dev/pty?? device. + + Instead, this code looks through all the devices in /dev for a device + which has the same inode as our PTY_FILENO descriptor... if found, we + have the name for our pty. + */ + + struct dirent *dirp; + DIR *dp; + struct stat dsb; + + if (fstat(fd, &dsb) != -1) { + if ((dp = opendir(_PATH_DEV)) != NULL) { + while ((dirp = readdir(dp))) { + if (dirp->d_fileno != dsb.st_ino) + continue; + pty = malloc(sizeof(_PATH_DEV) + strlen(dirp->d_name)); + if (pty) { + strcpy(pty, _PATH_DEV); + strcat(pty, dirp->d_name); + } + break; } - break; - } - (void) closedir(dp); + (void) closedir(dp); + } } } - } #endif - if (pty == NULL) - { - fprintf(stderr,"%s: cannot determine pty name.\n",argv[0]); - return 1; /* FAIL */ - } - close(fd); + if (pty == NULL) + { + fprintf(stderr,"%s: cannot determine pty name.\n",argv[0]); + return 1; /* FAIL */ + } - /* matches /dev/pty?? */ - if (strlen(pty) < 8 || strncmp(pty,"/dev/pty",8)) - { - fprintf(stderr,"%s: determined a strange pty name `%s'.\n",argv[0],pty); - return 1; /* FAIL */ - } + /* matches /dev/pty?? */ + if (memcmp(pty,"/dev/pty",8)) + { + fprintf(stderr,"%s: determined a strange pty name `%s'.\n",argv[0],pty); + return 1; /* FAIL */ + } - tty = malloc(strlen(pty) + 1); - strcpy(tty,"/dev/tty"); - strcat(tty,pty+8); + tty = malloc(strlen(pty) + 1); + strcpy(tty,"/dev/tty"); + strcat(tty,pty+8); + } /* Check that the returned slave pseudo terminal is a character device. */ @@ -160,4 +144,22 @@ } + /* setup parameters for the operation ***********************************/ + + if (!strcmp(argv[1],"--grant")) + { + uid = getuid(); + p = getgrnam(TTY_GROUP); + if (!p) + p = getgrnam("wheel"); + gid = p ? p->gr_gid : getgid (); + mod = S_IRUSR | S_IWUSR | S_IWGRP; + } + else + { + uid = 0; + gid = st.st_gid == getgid () ? 0 : -1; + mod = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH; + } + /* Perform the actual chown/chmod ************************************/ @@ -174,12 +176,4 @@ } -#ifdef BSD - if (revoke(tty) < 0) - { - fprintf(stderr,"%s: cannot revoke %s: %s\n",argv[0],tty,strerror(errno)); - return 1; /* FAIL */ - } -#endif - return 0; /* OK */ } Index: kpty.cpp =================================================================== RCS file: /home/kde/kdelibs/kdecore/kpty.cpp,v retrieving revision 1.18 diff -U2 -r1.18 kpty.cpp --- kpty.cpp 13 Jan 2004 01:02:29 -0000 1.18 +++ kpty.cpp 13 Jan 2004 17:36:44 -0000 @@ -159,5 +159,5 @@ struct KPtyPrivate { KPtyPrivate() : - xonXoff(false), needGrantPty(false), + xonXoff(false), masterFd(-1), slaveFd(-1) { @@ -168,5 +168,4 @@ bool xonXoff : 1; - bool needGrantPty : 1; int masterFd; int slaveFd; @@ -204,13 +203,6 @@ // We try, as we know them, one by one. -#if defined(HAVE_OPENPTY) - if (openpty(&d->masterFd, &d->slaveFd, NULL, NULL, NULL) == 0) - { - d->ttyName = ttyname(d->slaveFd); - goto gotpty2; - } -#endif -#if defined(HAVE_PTSNAME) +#if defined(HAVE_PTSNAME) && defined(HAVE_GRANTPT) #ifdef _AIX d->masterFd = ::open("/dev/ptc",O_RDWR); @@ -222,6 +214,7 @@ char *ptsn = ptsname(d->masterFd); if (ptsn) { + grantpt(d->masterFd); d->ttyName = ptsn; - goto gotpty1; + goto gotpty; } else { ::close(d->masterFd); @@ -254,6 +247,18 @@ } #endif /* sun */ - if (geteuid() == 0 || access(d->ttyName.data(),R_OK|W_OK) == 0) - goto gotpty1; // Success !! + if (!access(d->ttyName.data(),R_OK|W_OK)) // checks availability based on permission bits + { + if (!geteuid()) + { + struct group* p = getgrnam(TTY_GROUP); + if (!p) + p = getgrnam("wheel"); + gid_t gid = p ? p->gr_gid : getgid (); + + chown(d->ttyName.data(), getuid(), gid); + chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP); + } + goto gotpty; + } ::close(d->masterFd); d->masterFd = -1; @@ -265,28 +270,11 @@ return false; - gotpty1: -#if defined(HAVE_GRANTPT) - grantpt(d->masterFd); -#else - { - /* Get the group ID of the special `tty' group. */ - struct group* p = getgrnam(TTY_GROUP); /* posix */ - gid_t gid = p ? p->gr_gid : getgid (); /* posix */ - - chown(d->ttyName.data(), getuid(), gid); - chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IWGRP); - } -#endif - gotpty2: + gotpty: struct stat st; if (stat(d->ttyName.data(), &st)) return false; // this just cannot happen ... *cough* - d->needGrantPty = st.st_uid != getuid() || (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH)); - -#ifdef BSD - revoke(d->ttyName.data()); -#endif - - if (!chownpty(true)) + if (((st.st_uid != getuid()) || + (st.st_mode & (S_IRGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH))) && + !chownpty(true)) { kdWarning(175) @@ -295,17 +283,19 @@ } +#ifdef BSD + revoke(d->ttyName.data()); +#endif + #ifdef HAVE_UNLOCKPT unlockpt(d->masterFd); #endif - if (d->slaveFd < 0) { // slave pty not yet opened? - d->slaveFd = ::open(d->ttyName, O_RDWR); - if (d->slaveFd < 0) - { - kdWarning(175) << "Can't open slave pseudo teletype" << endl; - ::close(d->masterFd); - d->masterFd = -1; - return false; - } + d->slaveFd = ::open(d->ttyName.data(), O_RDWR); + if (d->slaveFd < 0) + { + kdWarning(175) << "Can't open slave pseudo teletype" << endl; + ::close(d->masterFd); + d->masterFd = -1; + return false; } @@ -348,7 +338,17 @@ if (d->masterFd < 0) return; - chown(d->ttyName.data(), 0, 0); - chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); - chownpty(false); + // don't bother resetting unix98 pty, it will go away after closing master anyway. + if (memcmp(d->ttyName.data(), "/dev/pts/", 9)) { + if (!geteuid()) { + struct stat st; + if (!stat(d->ttyName.data(), &st)) { + chown(d->ttyName.data(), 0, st.st_gid == getgid() ? 0 : -1); + chmod(d->ttyName.data(), S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); + } + } else { + fcntl(d->masterFd, F_SETFD, 0); + chownpty(false); + } + } ::close(d->slaveFd); ::close(d->masterFd); @@ -492,8 +492,4 @@ bool KPty::chownpty(bool grant) { - if (!d->needGrantPty) - return true; - - fcntl(d->masterFd, F_SETFD, 0); KProcess proc; proc << locate("exe", BASE_CHOWN) << (grant?"--grant":"--revoke") << QString::number(d->masterFd);