]> git.ipfire.org Git - thirdparty/glibc.git/blame - nis/nss_nis/nis-network.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / nis / nss_nis / nis-network.c
CommitLineData
f7a9f785 1/* Copyright (C) 1996-2016 Free Software Foundation, Inc.
6259ec0d
UD
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
6259ec0d
UD
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
6259ec0d 14
41bdb6e2 15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
6259ec0d
UD
18
19#include <nss.h>
b677d674
UD
20/* The following is an ugly trick to avoid a prototype declaration for
21 _nss_nis_endgrent. */
22#define _nss_nis_endnetent _nss_nis_endnetent_XXX
6259ec0d 23#include <netdb.h>
b677d674 24#undef _nss_nis_endnetent
6259ec0d
UD
25#include <ctype.h>
26#include <errno.h>
9b48fa9b 27#include <stdint.h>
6259ec0d
UD
28#include <string.h>
29#include <netinet/in.h>
30#include <arpa/inet.h>
ec999b8e 31#include <libc-lock.h>
6259ec0d
UD
32#include <rpcsvc/yp.h>
33#include <rpcsvc/ypclnt.h>
34
35#include "nss-nis.h"
36
7e3be507
UD
37/* Get the declaration of the parser function. */
38#define ENTNAME netent
39#define EXTERN_PARSER
cf29ffbe 40#include <nss/nss_files/files-parse.c>
7e3be507 41
6259ec0d
UD
42__libc_lock_define_initialized (static, lock)
43
44static bool_t new_start = 1;
fc9f33e3
UD
45static char *oldkey;
46static int oldkeylen;
6259ec0d
UD
47
48enum nss_status
51eecc4a 49_nss_nis_setnetent (int stayopen)
6259ec0d
UD
50{
51 __libc_lock_lock (lock);
52
53 new_start = 1;
54 if (oldkey != NULL)
55 {
56 free (oldkey);
57 oldkey = NULL;
58 oldkeylen = 0;
59 }
60
61 __libc_lock_unlock (lock);
62
63 return NSS_STATUS_SUCCESS;
64}
b677d674
UD
65/* Make _nss_nis_endnetent an alias of _nss_nis_setnetent. We do this
66 even though the prototypes don't match. The argument of setnetent
67 is not used so this makes no difference. */
68strong_alias (_nss_nis_setnetent, _nss_nis_endnetent)
6259ec0d
UD
69
70static enum nss_status
71internal_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
d71b808a 72 int *errnop, int *herrnop)
6259ec0d 73{
7e3be507 74 struct parser_data *data = (void *) buffer;
6259ec0d 75
ab9a9ff8 76 char *domain;
a1ffb40e 77 if (__glibc_unlikely (yp_get_default_domain (&domain)))
6259ec0d
UD
78 return NSS_STATUS_UNAVAIL;
79
80 /* Get the next entry until we found a correct one. */
ab9a9ff8 81 int parse_res;
6259ec0d
UD
82 do
83 {
ab9a9ff8
UD
84 char *result;
85 char *outkey;
86 int len;
87 int keylen;
88 int yperr;
6259ec0d
UD
89
90 if (new_start)
ab9a9ff8
UD
91 yperr = yp_first (domain, "networks.byname", &outkey, &keylen, &result,
92 &len);
6259ec0d 93 else
ab9a9ff8
UD
94 yperr = yp_next (domain, "networks.byname", oldkey, oldkeylen, &outkey,
95 &keylen, &result, &len);
6259ec0d 96
a1ffb40e 97 if (__glibc_unlikely (yperr != YPERR_SUCCESS))
6259ec0d 98 {
ab9a9ff8
UD
99 enum nss_status retval = yperr2nss (yperr);
100
34816665 101 if (retval == NSS_STATUS_TRYAGAIN)
6259ec0d
UD
102 {
103 *herrnop = NETDB_INTERNAL;
d71b808a 104 *errnop = errno;
6259ec0d
UD
105 }
106 return retval;
107 }
108
a1ffb40e 109 if (__glibc_unlikely ((size_t) (len + 1) > buflen))
6259ec0d
UD
110 {
111 free (result);
ac9f45cf 112 *errnop = ERANGE;
6259ec0d
UD
113 *herrnop = NETDB_INTERNAL;
114 return NSS_STATUS_TRYAGAIN;
115 }
116
ab9a9ff8 117 char *p = strncpy (buffer, result, len);
6259ec0d
UD
118 buffer[len] = '\0';
119 while (isspace (*p))
120 ++p;
121 free (result);
122
d71b808a 123 parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
a1ffb40e 124 if (__glibc_unlikely (parse_res == -1))
6259ec0d 125 {
60c96635 126 free (outkey);
6259ec0d 127 *herrnop = NETDB_INTERNAL;
d71b808a 128 *errnop = ERANGE;
6259ec0d
UD
129 return NSS_STATUS_TRYAGAIN;
130 }
131
132 free (oldkey);
133 oldkey = outkey;
134 oldkeylen = keylen;
135 new_start = 0;
136 }
137 while (!parse_res);
138
139 return NSS_STATUS_SUCCESS;
140}
141
142enum nss_status
143_nss_nis_getnetent_r (struct netent *net, char *buffer, size_t buflen,
d71b808a 144 int *errnop, int *herrnop)
6259ec0d
UD
145{
146 enum nss_status status;
147
148 __libc_lock_lock (lock);
149
d71b808a 150 status = internal_nis_getnetent_r (net, buffer, buflen, errnop, herrnop);
6259ec0d
UD
151
152 __libc_lock_unlock (lock);
153
154 return status;
155}
156
157enum nss_status
d71b808a
UD
158_nss_nis_getnetbyname_r (const char *name, struct netent *net, char *buffer,
159 size_t buflen, int *errnop, int *herrnop)
6259ec0d 160{
6259ec0d
UD
161 if (name == NULL)
162 {
ac9f45cf 163 *errnop = EINVAL;
6259ec0d
UD
164 *herrnop = NETDB_INTERNAL;
165 return NSS_STATUS_UNAVAIL;
166 }
167
ab9a9ff8 168 char *domain;
a1ffb40e 169 if (__glibc_unlikely (yp_get_default_domain (&domain)))
6259ec0d
UD
170 return NSS_STATUS_UNAVAIL;
171
ab9a9ff8 172 struct parser_data *data = (void *) buffer;
b112c02f
UD
173 if (buflen < sizeof *data + 1)
174 {
175 *herrnop = NETDB_INTERNAL;
176 *errnop = ERANGE;
177 return NSS_STATUS_TRYAGAIN;
178 }
b112c02f 179
ab9a9ff8
UD
180 /* Convert name to lowercase. */
181 size_t namlen = strlen (name);
315eb1d8
AS
182 /* Limit name length to the maximum size of an RPC packet. */
183 if (namlen > UDPMSGSIZE)
184 {
185 *errnop = ERANGE;
186 return NSS_STATUS_UNAVAIL;
187 }
188
ab9a9ff8
UD
189 char name2[namlen + 1];
190 size_t i;
b112c02f 191
ab9a9ff8
UD
192 for (i = 0; i < namlen; ++i)
193 name2[i] = _tolower (name[i]);
194 name2[i] = '\0';
b112c02f 195
ab9a9ff8
UD
196 char *result;
197 int len;
198 int yperr = yp_match (domain, "networks.byname", name2, namlen, &result,
199 &len);
6259ec0d 200
a1ffb40e 201 if (__glibc_unlikely (yperr != YPERR_SUCCESS))
6259ec0d 202 {
ab9a9ff8
UD
203 enum nss_status retval = yperr2nss (yperr);
204
34816665 205 if (retval == NSS_STATUS_TRYAGAIN)
6259ec0d 206 {
d71b808a 207 *errnop = errno;
6259ec0d
UD
208 *herrnop = NETDB_INTERNAL;
209 }
210 return retval;
211 }
212
a1ffb40e 213 if (__glibc_unlikely ((size_t) (len + 1) > buflen))
6259ec0d
UD
214 {
215 free (result);
d71b808a 216 *errnop = ERANGE;
6259ec0d
UD
217 *herrnop = NETDB_INTERNAL;
218 return NSS_STATUS_TRYAGAIN;
219 }
220
ab9a9ff8 221 char *p = strncpy (buffer, result, len);
6259ec0d
UD
222 buffer[len] = '\0';
223 while (isspace (*p))
224 ++p;
225 free (result);
226
ab9a9ff8 227 int parse_res = _nss_files_parse_netent (p, net, data, buflen, errnop);
6259ec0d 228
a1ffb40e 229 if (__glibc_unlikely (parse_res < 1))
6259ec0d
UD
230 {
231 *herrnop = NETDB_INTERNAL;
60c96635 232 if (parse_res == -1)
6259ec0d
UD
233 return NSS_STATUS_TRYAGAIN;
234 else
34816665 235 return NSS_STATUS_NOTFOUND;
6259ec0d
UD
236 }
237 else
238 return NSS_STATUS_SUCCESS;
239}
240
241enum nss_status
9b48fa9b 242_nss_nis_getnetbyaddr_r (uint32_t addr, int type, struct netent *net,
d71b808a
UD
243 char *buffer, size_t buflen, int *errnop,
244 int *herrnop)
6259ec0d
UD
245{
246 char *domain;
a1ffb40e 247 if (__glibc_unlikely (yp_get_default_domain (&domain)))
6259ec0d
UD
248 return NSS_STATUS_UNAVAIL;
249
2fd0cd8b 250 struct in_addr in = { .s_addr = htonl (addr) };
ab9a9ff8
UD
251 char *buf = inet_ntoa (in);
252 size_t blen = strlen (buf);
6259ec0d
UD
253
254 while (1)
255 {
ab9a9ff8
UD
256 char *result;
257 int len;
6259ec0d 258
ab9a9ff8
UD
259 int yperr = yp_match (domain, "networks.byaddr", buf, blen, &result,
260 &len);
6259ec0d 261
a1ffb40e 262 if (__glibc_unlikely (yperr != YPERR_SUCCESS))
6259ec0d 263 {
ab9a9ff8
UD
264 enum nss_status retval = yperr2nss (yperr);
265
6259ec0d
UD
266 if (retval == NSS_STATUS_NOTFOUND)
267 {
268 if (buf[blen - 2] == '.' && buf[blen - 1] == '0')
269 {
270 /* Try again, but with trailing dot(s)
271 removed (one by one) */
272 buf[blen - 2] = '\0';
273 blen -= 2;
274 continue;
275 }
276 else
34816665 277 return NSS_STATUS_NOTFOUND;
6259ec0d
UD
278 }
279 else
280 {
281 if (retval == NSS_STATUS_TRYAGAIN)
d71b808a 282 *errnop = errno;
6259ec0d
UD
283 return retval;
284 }
285 }
286
a1ffb40e 287 if (__glibc_unlikely ((size_t) (len + 1) > buflen))
6259ec0d
UD
288 {
289 free (result);
d71b808a 290 *errnop = ERANGE;
6259ec0d
UD
291 *herrnop = NETDB_INTERNAL;
292 return NSS_STATUS_TRYAGAIN;
293 }
294
ab9a9ff8 295 char *p = strncpy (buffer, result, len);
6259ec0d
UD
296 buffer[len] = '\0';
297 while (isspace (*p))
298 ++p;
299 free (result);
300
ab9a9ff8
UD
301 int parse_res = _nss_files_parse_netent (p, net, (void *) buffer,
302 buflen, errnop);
6259ec0d 303
a1ffb40e 304 if (__glibc_unlikely (parse_res < 1))
6259ec0d
UD
305 {
306 *herrnop = NETDB_INTERNAL;
60c96635 307 if (parse_res == -1)
6259ec0d
UD
308 return NSS_STATUS_TRYAGAIN;
309 else
34816665 310 return NSS_STATUS_NOTFOUND;
6259ec0d
UD
311 }
312 else
313 return NSS_STATUS_SUCCESS;
314 }
315}