]> granicus.if.org Git - shadow/blob - libmisc/rlogin.c
* NEWS, libmisc/chowntty.c: Fix a race condition that could lead to
[shadow] / libmisc / rlogin.c
1 /*
2  * Copyright (c) 1989 - 1994, Julianne Frances Haugh
3  * Copyright (c) 1996 - 1999, Marek Michałkiewicz
4  * Copyright (c) 2003 - 2005, Tomasz Kłoczko
5  * Copyright (c) 2007 - 2008, Nicolas François
6  * 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. The name of the copyright holders or contributors may not be used to
17  *    endorse or promote products derived from this software without
18  *    specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT
24  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32
33 #include <config.h>
34
35 #ifdef RLOGIN
36
37 #ident "$Id$"
38
39 #include "prototypes.h"
40 #include "defines.h"
41 #include <stdio.h>
42 #include <pwd.h>
43 #include <netdb.h>
44 static struct {
45         int spd_name;
46         int spd_baud;
47 } speed_table[] =
48 {
49 #ifdef B50
50         {
51         B50, 50},
52 #endif
53 #ifdef B75
54         {
55         B75, 75},
56 #endif
57 #ifdef B110
58         {
59         B110, 110},
60 #endif
61 #ifdef B134
62         {
63         B134, 134},
64 #endif
65 #ifdef B150
66         {
67         B150, 150},
68 #endif
69 #ifdef B200
70         {
71         B200, 200},
72 #endif
73 #ifdef B300
74         {
75         B300, 300},
76 #endif
77 #ifdef B600
78         {
79         B600, 600},
80 #endif
81 #ifdef B1200
82         {
83         B1200, 1200},
84 #endif
85 #ifdef B1800
86         {
87         B1800, 1800},
88 #endif
89 #ifdef B2400
90         {
91         B2400, 2400},
92 #endif
93 #ifdef B4800
94         {
95         B4800, 4800},
96 #endif
97 #ifdef B9600
98         {
99         B9600, 9600},
100 #endif
101 #ifdef B19200
102         {
103         B19200, 19200},
104 #endif
105 #ifdef B38400
106         {
107         B38400, 38400},
108 #endif
109         {
110         -1, -1}
111 };
112
113 static void get_remote_string (char *buf, size_t size)
114 {
115         for (;;) {
116                 if (read (0, buf, 1) != 1) {
117                         exit (1);
118                 }
119                 if ('\0' == *buf) {
120                         return;
121                 }
122                 --size;
123                 if (size > 0) {
124                         ++buf;
125                 }
126         }
127  /*NOTREACHED*/}
128
129 int
130 do_rlogin (const char *remote_host, char *name, size_t namelen, char *term,
131            size_t termlen)
132 {
133         struct passwd *pwd;
134         char remote_name[32];
135         char *cp;
136         int remote_speed = 9600;
137         int speed_name = B9600;
138         int i;
139         TERMIO termio;
140
141         get_remote_string (remote_name, sizeof remote_name);
142         get_remote_string (name, namelen);
143         get_remote_string (term, termlen);
144
145         cp = strchr (term, '/');
146         if (NULL != cp) {
147                 *cp = '\0';
148                 cp++;
149
150                 remote_speed = atoi (cp);
151                 if (0 == remote_speed) {
152                         remote_speed = 9600;
153                 }
154         }
155         for (i = 0;
156              (   (speed_table[i].spd_baud != remote_speed)
157               && (speed_table[i].spd_name != -1));
158              i++);
159
160         if (-1 != speed_table[i].spd_name) {
161                 speed_name = speed_table[i].spd_name;
162         }
163
164         /*
165          * Put the terminal in cooked mode with echo turned on.
166          */
167
168         GTTY (0, &termio);
169         termio.c_iflag |= ICRNL | IXON;
170         termio.c_oflag |= OPOST | ONLCR;
171         termio.c_lflag |= ICANON | ECHO | ECHOE;
172 #ifdef CBAUD
173         termio.c_cflag = (termio.c_cflag & ~CBAUD) | speed_name;
174 #else
175         termio.c_cflag = (termio.c_cflag) | speed_name;
176 #endif
177         STTY (0, &termio);
178
179         pwd = getpwnam (name); /* local, no need for xgetpwnam */
180         if (NULL == pwd) {
181                 return 0;
182         }
183
184         /*
185          * ruserok() returns 0 for success on modern systems, and 1 on
186          * older ones.  If you are having trouble with people logging
187          * in without giving a required password, THIS is the culprit -
188          * go fix the #define in config.h.
189          */
190
191 #ifndef RUSEROK
192         return 0;
193 #else
194         return ruserok (remote_host, pwd->pw_uid == 0,
195                         remote_name, name) == RUSEROK;
196 #endif
197 }
198 #endif                          /* RLOGIN */
199