]> git.ipfire.org Git - thirdparty/glibc.git/blame - nis/nss_nis/nis-ethers.c
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / nis / nss_nis / nis-ethers.c
CommitLineData
04277e02 1/* Copyright (C) 1996-2019 Free Software Foundation, Inc.
6259ec0d 2 This file is part of the GNU C Library.
b85697f6 3 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
6259ec0d
UD
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>
20#include <ctype.h>
21#include <errno.h>
22#include <string.h>
ec999b8e 23#include <libc-lock.h>
6259ec0d
UD
24#include <rpcsvc/yp.h>
25#include <rpcsvc/ypclnt.h>
6b083d46 26#include <netinet/ether.h>
6259ec0d
UD
27#include <netinet/if_ether.h>
28
29#include "nss-nis.h"
30
31/* Protect global state against multiple changers */
32__libc_lock_define_initialized (static, lock)
33
7e3be507
UD
34/* Get the declaration of the parser function. */
35#define ENTNAME etherent
6b083d46 36#define STRUCTURE etherent
7e3be507 37#define EXTERN_PARSER
cf29ffbe 38#include <nss/nss_files/files-parse.c>
7e3be507 39
f166d865
UD
40struct response
41{
f166d865 42 struct response *next;
b569ae38 43 char val[0];
f166d865 44};
6259ec0d 45
fc9f33e3
UD
46static struct response *start;
47static struct response *next;
f166d865
UD
48
49static int
0d8733c4 50saveit (int instatus, char *inkey, int inkeylen, char *inval,
f166d865 51 int invallen, char *indata)
6259ec0d 52{
f166d865 53 if (instatus != YP_TRUE)
08c9a553 54 return 1;
f166d865
UD
55
56 if (inkey && inkeylen > 0 && inval && invallen > 0)
57 {
b569ae38
UD
58 struct response *newp = malloc (sizeof (struct response) + invallen + 1);
59 if (newp == NULL)
08c9a553 60 return 1; /* We have no error code for out of memory */
b569ae38 61
f166d865 62 if (start == NULL)
b569ae38 63 start = newp;
f166d865 64 else
b569ae38
UD
65 next->next = newp;
66 next = newp;
67
68 newp->next = NULL;
69 *((char *) mempcpy (newp->val, inval, invallen)) = '\0';
f166d865 70 }
0d8733c4 71
f166d865
UD
72 return 0;
73}
6259ec0d 74
6675b191
UD
75static void
76internal_nis_endetherent (void)
f166d865 77{
f166d865 78 while (start != NULL)
6259ec0d 79 {
f166d865
UD
80 next = start;
81 start = start->next;
82 free (next);
6259ec0d 83 }
6675b191
UD
84}
85
86enum nss_status
87_nss_nis_endetherent (void)
88{
89 __libc_lock_lock (lock);
90
91 internal_nis_endetherent ();
92 next = NULL;
93
94 __libc_lock_unlock (lock);
95
96 return NSS_STATUS_SUCCESS;
97}
98
99static enum nss_status
100internal_nis_setetherent (void)
101{
102 char *domainname;
103 struct ypall_callback ypcb;
104 enum nss_status status;
105
106 yp_get_default_domain (&domainname);
107
108 internal_nis_endetherent ();
6259ec0d 109
f166d865
UD
110 ypcb.foreach = saveit;
111 ypcb.data = NULL;
0d8733c4 112 status = yperr2nss (yp_all (domainname, "ethers.byname", &ypcb));
f166d865 113 next = start;
6259ec0d 114
0d8733c4 115 return status;
6259ec0d
UD
116}
117
f166d865 118enum nss_status
ed073f0e 119_nss_nis_setetherent (int stayopen)
f166d865
UD
120{
121 enum nss_status result;
122
123 __libc_lock_lock (lock);
124
125 result = internal_nis_setetherent ();
126
127 __libc_lock_unlock (lock);
128
129 return result;
130}
0d8733c4 131
6259ec0d 132static enum nss_status
6b083d46 133internal_nis_getetherent_r (struct etherent *eth, char *buffer, size_t buflen,
d71b808a 134 int *errnop)
6259ec0d 135{
7e3be507 136 struct parser_data *data = (void *) buffer;
f166d865 137 int parse_res;
6259ec0d 138
f166d865
UD
139 if (start == NULL)
140 internal_nis_setetherent ();
6259ec0d
UD
141
142 /* Get the next entry until we found a correct one. */
143 do
144 {
6259ec0d 145 char *p;
0d8733c4 146
f166d865 147 if (next == NULL)
34816665
UD
148 return NSS_STATUS_NOTFOUND;
149
9756dfe1 150 p = strncpy (buffer, next->val, buflen);
0d8733c4 151
6259ec0d
UD
152 while (isspace (*p))
153 ++p;
0d8733c4 154
d71b808a
UD
155 parse_res = _nss_files_parse_etherent (p, eth, data, buflen, errnop);
156 if (parse_res == -1)
60c96635
UD
157 return NSS_STATUS_TRYAGAIN;
158 next = next->next;
6259ec0d
UD
159 }
160 while (!parse_res);
d71b808a 161
6259ec0d
UD
162 return NSS_STATUS_SUCCESS;
163}
164
165enum nss_status
6b083d46 166_nss_nis_getetherent_r (struct etherent *result, char *buffer, size_t buflen,
d71b808a 167 int *errnop)
6259ec0d
UD
168{
169 int status;
170
171 __libc_lock_lock (lock);
172
d71b808a 173 status = internal_nis_getetherent_r (result, buffer, buflen, errnop);
6259ec0d
UD
174
175 __libc_lock_unlock (lock);
176
177 return status;
178}
179
180enum nss_status
6b083d46 181_nss_nis_gethostton_r (const char *name, struct etherent *eth,
d71b808a 182 char *buffer, size_t buflen, int *errnop)
6259ec0d 183{
6259ec0d
UD
184 if (name == NULL)
185 {
ac9f45cf 186 *errnop = EINVAL;
6259ec0d
UD
187 return NSS_STATUS_UNAVAIL;
188 }
189
ab9a9ff8 190 char *domain;
a1ffb40e 191 if (__glibc_unlikely (yp_get_default_domain (&domain)))
6259ec0d
UD
192 return NSS_STATUS_UNAVAIL;
193
ab9a9ff8
UD
194 char *result;
195 int len;
196 int yperr = yp_match (domain, "ethers.byname", name, strlen (name), &result,
197 &len);
6259ec0d 198
a1ffb40e 199 if (__glibc_unlikely (yperr != YPERR_SUCCESS))
6259ec0d 200 {
ab9a9ff8
UD
201 enum nss_status retval = yperr2nss (yperr);
202
34816665 203 if (retval == NSS_STATUS_TRYAGAIN)
d71b808a 204 *errnop = errno;
6259ec0d
UD
205 return retval;
206 }
207
a1ffb40e 208 if (__glibc_unlikely ((size_t) (len + 1) > buflen))
6259ec0d
UD
209 {
210 free (result);
d71b808a 211 *errnop = ERANGE;
6259ec0d
UD
212 return NSS_STATUS_TRYAGAIN;
213 }
214
ab9a9ff8 215 char *p = strncpy (buffer, result, len);
6259ec0d
UD
216 buffer[len] = '\0';
217 while (isspace (*p))
218 ++p;
219 free (result);
220
ab9a9ff8
UD
221 int parse_res = _nss_files_parse_etherent (p, eth, (void *) buffer, buflen,
222 errnop);
a1ffb40e 223 if (__glibc_unlikely (parse_res < 1))
ac9f45cf
UD
224 {
225 if (parse_res == -1)
226 return NSS_STATUS_TRYAGAIN;
227 else
34816665 228 return NSS_STATUS_NOTFOUND;
ac9f45cf
UD
229 }
230 return NSS_STATUS_SUCCESS;
6259ec0d
UD
231}
232
233enum nss_status
6b083d46 234_nss_nis_getntohost_r (const struct ether_addr *addr, struct etherent *eth,
d71b808a 235 char *buffer, size_t buflen, int *errnop)
6259ec0d 236{
6259ec0d
UD
237 if (addr == NULL)
238 {
ac9f45cf 239 *errnop = EINVAL;
6259ec0d
UD
240 return NSS_STATUS_UNAVAIL;
241 }
242
ab9a9ff8 243 char *domain;
a1ffb40e 244 if (__glibc_unlikely (yp_get_default_domain (&domain)))
6259ec0d
UD
245 return NSS_STATUS_UNAVAIL;
246
ab9a9ff8
UD
247 char buf[33];
248 int nlen = snprintf (buf, sizeof (buf), "%x:%x:%x:%x:%x:%x",
249 (int) addr->ether_addr_octet[0],
250 (int) addr->ether_addr_octet[1],
251 (int) addr->ether_addr_octet[2],
252 (int) addr->ether_addr_octet[3],
253 (int) addr->ether_addr_octet[4],
254 (int) addr->ether_addr_octet[5]);
255
256 char *result;
257 int len;
258 int yperr = yp_match (domain, "ethers.byaddr", buf, nlen, &result, &len);
259
a1ffb40e 260 if (__glibc_unlikely (yperr != YPERR_SUCCESS))
a334319f 261 {
ab9a9ff8
UD
262 enum nss_status retval = yperr2nss (yperr);
263
6259ec0d 264 if (retval == NSS_STATUS_TRYAGAIN)
d71b808a 265 *errnop = errno;
6259ec0d
UD
266 return retval;
267 }
268
a1ffb40e 269 if (__glibc_unlikely ((size_t) (len + 1) > buflen))
6259ec0d
UD
270 {
271 free (result);
d71b808a 272 *errnop = ERANGE;
6259ec0d
UD
273 return NSS_STATUS_TRYAGAIN;
274 }
275
ab9a9ff8 276 char *p = strncpy (buffer, result, len);
6259ec0d
UD
277 buffer[len] = '\0';
278 while (isspace (*p))
279 ++p;
280 free (result);
281
ab9a9ff8
UD
282 int parse_res = _nss_files_parse_etherent (p, eth, (void *) buffer, buflen,
283 errnop);
a1ffb40e 284 if (__glibc_unlikely (parse_res < 1))
ac9f45cf
UD
285 {
286 if (parse_res == -1)
287 return NSS_STATUS_TRYAGAIN;
288 else
34816665 289 return NSS_STATUS_NOTFOUND;
ac9f45cf
UD
290 }
291 return NSS_STATUS_SUCCESS;
6259ec0d 292}