Line data Source code
1 : /* $OpenBSD: tty_tty.c,v 1.24 2018/05/02 02:24:56 visa Exp $ */
2 : /* $NetBSD: tty_tty.c,v 1.13 1996/03/30 22:24:46 christos Exp $ */
3 :
4 : /*-
5 : * Copyright (c) 1982, 1986, 1991, 1993
6 : * The Regents of the University of California. All rights reserved.
7 : *
8 : * Redistribution and use in source and binary forms, with or without
9 : * modification, are permitted provided that the following conditions
10 : * are met:
11 : * 1. Redistributions of source code must retain the above copyright
12 : * notice, this list of conditions and the following disclaimer.
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : * 3. Neither the name of the University nor the names of its contributors
17 : * may be used to endorse or promote products derived from this software
18 : * without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 : * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 : * SUCH DAMAGE.
31 : *
32 : * @(#)tty_tty.c 8.2 (Berkeley) 9/23/93
33 : */
34 :
35 : /*
36 : * Indirect driver for controlling tty.
37 : */
38 : #include <sys/param.h>
39 : #include <sys/systm.h>
40 : #include <sys/ioctl.h>
41 : #include <sys/proc.h>
42 : #include <sys/tty.h>
43 : #include <sys/vnode.h>
44 : #include <sys/lock.h>
45 : #include <sys/fcntl.h>
46 :
47 :
48 : #define cttyvp(p) \
49 : ((p)->p_p->ps_flags & PS_CONTROLT ? \
50 : (p)->p_p->ps_session->s_ttyvp : NULL)
51 :
52 : int
53 0 : cttyopen(dev_t dev, int flag, int mode, struct proc *p)
54 : {
55 0 : struct vnode *ttyvp = cttyvp(p);
56 : int error;
57 :
58 0 : if (ttyvp == NULL)
59 0 : return (ENXIO);
60 0 : vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY);
61 0 : error = VOP_OPEN(ttyvp, flag, NOCRED, p);
62 0 : VOP_UNLOCK(ttyvp);
63 0 : return (error);
64 0 : }
65 :
66 : int
67 0 : cttyread(dev_t dev, struct uio *uio, int flag)
68 : {
69 0 : struct vnode *ttyvp = cttyvp(uio->uio_procp);
70 : int error;
71 :
72 0 : if (ttyvp == NULL)
73 0 : return (EIO);
74 0 : vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY);
75 0 : error = VOP_READ(ttyvp, uio, flag, NOCRED);
76 0 : VOP_UNLOCK(ttyvp);
77 0 : return (error);
78 0 : }
79 :
80 : int
81 0 : cttywrite(dev_t dev, struct uio *uio, int flag)
82 : {
83 0 : struct vnode *ttyvp = cttyvp(uio->uio_procp);
84 : int error;
85 :
86 0 : if (ttyvp == NULL)
87 0 : return (EIO);
88 0 : vn_lock(ttyvp, LK_EXCLUSIVE | LK_RETRY);
89 0 : error = VOP_WRITE(ttyvp, uio, flag, NOCRED);
90 0 : VOP_UNLOCK(ttyvp);
91 0 : return (error);
92 0 : }
93 :
94 : int
95 0 : cttyioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
96 : {
97 0 : struct vnode *ttyvp = cttyvp(p);
98 : struct session *sess;
99 : int error, secs;
100 :
101 0 : if (ttyvp == NULL)
102 0 : return (EIO);
103 0 : if (cmd == TIOCSCTTY) /* XXX */
104 0 : return (EINVAL);
105 0 : if (cmd == TIOCNOTTY) {
106 0 : if (!SESS_LEADER(p->p_p)) {
107 0 : atomic_clearbits_int(&p->p_p->ps_flags, PS_CONTROLT);
108 0 : return (0);
109 : } else
110 0 : return (EINVAL);
111 : }
112 0 : switch (cmd) {
113 : case TIOCSETVERAUTH:
114 0 : if ((error = suser(p)))
115 0 : return error;
116 0 : secs = *(int *)addr;
117 0 : if (secs < 1 || secs > 3600)
118 0 : return EINVAL;
119 0 : sess = p->p_p->ps_pgrp->pg_session;
120 0 : sess->s_verauthuid = p->p_ucred->cr_ruid;
121 0 : sess->s_verauthppid = p->p_p->ps_pptr->ps_pid;
122 0 : timeout_add_sec(&sess->s_verauthto, secs);
123 0 : return 0;
124 : case TIOCCLRVERAUTH:
125 0 : sess = p->p_p->ps_pgrp->pg_session;
126 0 : timeout_del(&sess->s_verauthto);
127 0 : zapverauth(sess);
128 0 : return 0;
129 : case TIOCCHKVERAUTH:
130 : /*
131 : * It's not clear when or what these checks are for.
132 : * How can we reach this code with a differnt ruid?
133 : * The ppid check is also more porous than desired.
134 : * Nevertheless, the checks reflect the original intention;
135 : * namely, that it be the same user using the same shell.
136 : */
137 0 : sess = p->p_p->ps_pgrp->pg_session;
138 0 : if (sess->s_verauthuid == p->p_ucred->cr_ruid &&
139 0 : sess->s_verauthppid == p->p_p->ps_pptr->ps_pid)
140 0 : return 0;
141 0 : return EPERM;
142 : }
143 0 : return (VOP_IOCTL(ttyvp, cmd, addr, flag, NOCRED, p));
144 0 : }
145 :
146 : int
147 0 : cttypoll(dev_t dev, int events, struct proc *p)
148 : {
149 0 : struct vnode *ttyvp = cttyvp(p);
150 :
151 0 : if (ttyvp == NULL) /* try operation to get EOF/failure */
152 0 : return (seltrue(dev, events, p));
153 0 : return (VOP_POLL(ttyvp, FREAD|FWRITE, events, p));
154 0 : }
155 :
156 : int
157 0 : cttykqfilter(dev_t dev, struct knote *kn)
158 : {
159 0 : struct vnode *ttyvp = cttyvp(curproc);
160 :
161 0 : if (ttyvp == NULL)
162 0 : return (ENXIO);
163 0 : return (VOP_KQFILTER(ttyvp, kn));
164 0 : }
|