]> sourceware.org Git - newlib-cygwin.git/blame - winsup/cygwin/libc/iruserok.c
* Makefile.in (DLL_OFILES): Add getopt.o and iruserok.o.
[newlib-cygwin.git] / winsup / cygwin / libc / iruserok.c
CommitLineData
34a1d63d
CV
1/* Based on the rcmd.c.new file distributed with linux libc 5.4.19
2 Adapted to inetutils by Bernhard Rosenkraenzer <bero@startrek.in-trier.de>
3
4 Note that a lot in this file is superfluous; hopefully it won't be a
5 problem for systems that need it for iruserok &c.... */
6/*
7 * Copyright (c) 1983, 1993, 1994
8 * The Regents of the University of California. All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 */
38
932a40e8 39#include "winsup.h"
34a1d63d 40#include <pwd.h>
34a1d63d 41#include <sys/stat.h>
34a1d63d 42#include <malloc.h>
932a40e8 43#include <string.h>
34a1d63d 44#include <netdb.h>
34a1d63d
CV
45#include <ctype.h>
46#include <stdio.h>
47#include <errno.h>
932a40e8
CV
48#include <sys/time.h>
49#include <time.h>
50
51#ifndef PATH_HEQUIV
52# define PATH_HEQUIV "/etc/hosts.equiv"
34a1d63d
CV
53#endif
54
932a40e8 55int __check_rhosts_file = 1;
34a1d63d
CV
56const char *__rcmd_errstr;
57
34a1d63d 58/*
932a40e8 59 * Returns "true" if match, 0 if no match.
34a1d63d 60 */
932a40e8
CV
61static int
62__icheckhost(raddr, lhost)
34a1d63d 63 u_long raddr;
932a40e8 64 register char *lhost;
34a1d63d 65{
932a40e8
CV
66 register struct hostent *hp;
67 register u_long laddr;
68 register char **pp;
34a1d63d 69
932a40e8
CV
70 /* Try for raw ip address first. */
71 if (isdigit(*lhost) && (long)(laddr = cygwin_inet_addr(lhost)) != -1)
72 return (raddr == laddr);
34a1d63d 73
932a40e8
CV
74 /* Better be a hostname. */
75 if ((hp = cygwin_gethostbyname(lhost)) == NULL)
76 return (0);
34a1d63d 77
932a40e8
CV
78 /* Spin through ip addresses. */
79 for (pp = hp->h_addr_list; *pp; ++pp)
80 if (!bcmp(&raddr, *pp, sizeof(u_long)))
81 return (1);
34a1d63d 82
932a40e8
CV
83 /* No match. */
84 return (0);
34a1d63d
CV
85}
86
87/*
88 * XXX
89 * Don't make static, used by lpd(8).
90 *
91 * Returns 0 if ok, -1 if not ok.
92 */
932a40e8 93static int
34a1d63d 94__ivaliduser(hostf, raddr, luser, ruser)
932a40e8 95 struct __sFILE64 *hostf;
34a1d63d
CV
96 u_long raddr;
97 const char *luser;
98 const char *ruser;
99{
100 size_t buf_offs = 0;
101 size_t buf_len = 256;
102 char *buf = malloc (buf_len);
103
104 if (! buf)
105 return -1;
106
107 while (fgets(buf + buf_offs, buf_len - buf_offs, hostf)) {
108 /*int ch;*/
109 register char *user, *p;
110
111 if (strchr(buf + buf_offs, '\n') == NULL) {
112 /* No newline yet, read some more. */
113 buf_offs += strlen (buf + buf_offs);
114
115 if (buf_offs >= buf_len - 1) {
116 /* Make more room in BUF. */
117 char *new_buf;
118
119 buf_len += buf_len;
120 new_buf = realloc (buf, buf_len);
121
122 if (! new_buf) {
123 free (buf);
124 return -1;
125 }
126
127 buf = new_buf;
128 }
129
130 continue;
131 }
132
133 buf_offs = 0; /* Start at beginning next time around. */
134
135 p = buf;
136 while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
137 /* *p = isupper(*p) ? tolower(*p) : *p; -- Uli */
138 *p = tolower(*p); /* works for linux libc */
139 p++;
140 }
141 if (*p == ' ' || *p == '\t') {
142 *p++ = '\0';
143 while (*p == ' ' || *p == '\t')
144 p++;
145 user = p;
146 while (*p != '\n' && *p != ' ' &&
147 *p != '\t' && *p != '\0')
148 p++;
149 } else
150 user = p;
151 *p = '\0';
152
153 if (__icheckhost(raddr, buf) && !strcmp(ruser, *user ? user : luser)) {
154 free (buf);
155 return (0);
156 }
157 }
158
159 free (buf);
160
161 return (-1);
162}
163
164/*
932a40e8
CV
165 * New .rhosts strategy: We are passed an ip address. We spin through
166 * hosts.equiv and .rhosts looking for a match. When the .rhosts only
167 * has ip addresses, we don't have to trust a nameserver. When it
168 * contains hostnames, we spin through the list of addresses the nameserver
169 * gives us and look for a match.
170 *
171 * Returns 0 if ok, -1 if not ok.
34a1d63d 172 */
34a1d63d 173int
932a40e8 174iruserok(raddr, superuser, ruser, luser)
34a1d63d 175 u_long raddr;
932a40e8
CV
176 int superuser;
177 const char *ruser;
178 const char *luser;
34a1d63d 179{
932a40e8
CV
180 register const char *cp;
181 struct __stat64 sbuf;
182 struct passwd *pwd;
183 struct __sFILE64 *hostf;
34a1d63d 184
932a40e8
CV
185 uid_t uid;
186 int first = 1;
187 char *pbuf;
34a1d63d 188
932a40e8
CV
189 first = 1;
190 hostf = superuser ? NULL : fopen64(PATH_HEQUIV, "rt");
191again:
192 if (hostf) {
193 if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
194 (void) fclose(hostf);
195 return(0);
196 }
197 (void) fclose(hostf);
198 }
199 if (first == 1 && (__check_rhosts_file || superuser)) {
200 first = 0;
201 if ((pwd = getpwnam(luser)) == NULL)
202 return(-1);
34a1d63d 203
932a40e8
CV
204 pbuf = malloc (strlen (pwd->pw_dir) + sizeof "/.rhosts");
205 if (! pbuf)
206 {
207 errno = ENOMEM;
208 return -1;
209 }
210 strcpy (pbuf, pwd->pw_dir);
211 strcat (pbuf, "/.rhosts");
34a1d63d 212
932a40e8
CV
213 /*
214 * Change effective uid while opening .rhosts. If root and
215 * reading an NFS mounted file system, can't read files that
216 * are protected read/write owner only.
217 */
218 uid = geteuid32();
219 (void)seteuid32(pwd->pw_uid);
220 hostf = fopen64(pbuf, "rt");
221 (void)seteuid32(uid);
222
223 if (hostf == NULL)
224 return(-1);
225 /*
226 * If not a regular file, or is owned by someone other than
227 * user or root or if writeable by anyone but the owner, quit.
228 */
229 cp = NULL;
230 if (lstat64(pbuf, &sbuf) < 0)
231 cp = ".rhosts not regular file";
232 else if (!S_ISREG(sbuf.st_mode))
233 cp = ".rhosts not regular file";
234 else if (fstat64(fileno(hostf), &sbuf) < 0)
235 cp = ".rhosts fstat failed";
236 else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
237 cp = "bad .rhosts owner";
238 else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
239 cp = ".rhosts writeable by other than owner";
240 /* If there were any problems, quit. */
241 if (cp) {
242 __rcmd_errstr = (char *) cp;
243 fclose(hostf);
244 return(-1);
245 }
246 goto again;
247 }
248 return (-1);
249}
250
251int
252ruserok(rhost, superuser, ruser, luser)
253 const char *rhost;
254 int superuser;
255 const char *ruser;
256 const char *luser;
257{
258 struct hostent *hp;
259 u_long addr;
260 char **ap;
261
262 if ((hp = cygwin_gethostbyname(rhost)) == NULL)
263 return (-1);
264 for (ap = hp->h_addr_list; *ap; ++ap) {
265 bcopy(*ap, &addr, sizeof(addr));
266 if (iruserok(addr, superuser, ruser, luser) == 0)
267 return (0);
268 }
269 return (-1);
34a1d63d 270}
This page took 0.05028 seconds and 5 git commands to generate.