[EMAIL PROTECTED] (Niels M�ller) writes:
> � Implement a better grantpt() function, which also takes a uid as
> argument. After a first reading of the glibc implementation
> (glibc-2.1.1pre1, available on ftp://alpha.gnu.org, in the file
> sysdeps/unix/grantpt.c), it seems that this is a lot easier than one
> might fear.
Well, I said it was easy... Here's my first attempt (also available at
http://www.lysator.liu.se/~nisse/lsh/src/server_pty.c). 75 lines. Do
you think something like this will do? Next question is whether or not
the tty_setctty works for UNIX98 sockets. And if it can be done in a
cleaner way than reopening the slave, this time without the O_NOCTTY
flag.
/* FIXME: Maybe this name should be configurable? */
#ifndef TTY_GROUP
#define TTY_GROUP "tty"
#endif
#ifndef ACCESSPERMS
#define ACCESSPERMS 07777
#endif
/* Sets the permissions on the slave pty suitably for use by USER.
* This function is derived from the grantpt function in
* sysdeps/unix/grantpt.c in glibc-2.1. */
/* Returns the name of the slave tty, as a string with an extra
* terminating NUL. */
static struct lsh_string *pty_grantpt_uid(int master, uid_t user)
{
uid_t me = getpid();
if (me == user)
{
/* Use standard grantpt call */
if (grantpt(master) < 0)
return NULL;
return format_cstring(ptsname(master));
}
else
{ /* Set up permissions for user */
/* Pointer to static area */
char *name = ptsname(master);
struct stat st;
struct group *grp;
gid_t tty_gid;
if (!name)
return NULL;
if (stat(name, &st) < 0)
return NULL;
/* Make sure that the user owns the device. */
if ( (st.st_uid != user)
&& (chown(name, user, st.st_gid) < 0) )
return NULL;
/* Points to static area */
grp = getgrnam(TTY_GROUP);
if (grp)
tty_gid = grp->gr_gid;
else
{
/* If no tty group is found, use the server's gid */
werror("lshd: server_pty.c: No tty group found.\n");
tty_gid = getgid();
}
if ( (st.st_gid != tty_gid)
&& (chown(name, user, tty_gid) < 0))
return NULL;
/* Make sure the permission mode is set to readable and writable
* by the owner, and writable by the group. */
if ( ((st.st_mode & ACCESSPERMS) != (S_IRUSR | S_IWUSR | S_IWGRP))
&& (chmod(name, S_IRUSR | S_IWUSR | S_IWGRP) < 0) )
return NULL;
/* Everything is fine */
return format_cstring(name);
}
}
#endif HAVE_UNIX98_PTYS