]>
Commit | Line | Data |
---|---|---|
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 |
40 | struct response |
41 | { | |
f166d865 | 42 | struct response *next; |
b569ae38 | 43 | char val[0]; |
f166d865 | 44 | }; |
6259ec0d | 45 | |
fc9f33e3 UD |
46 | static struct response *start; |
47 | static struct response *next; | |
f166d865 UD |
48 | |
49 | static int | |
0d8733c4 | 50 | saveit (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 |
75 | static void |
76 | internal_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 | ||
86 | enum 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 | ||
99 | static enum nss_status | |
100 | internal_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 | 118 | enum 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 | 132 | static enum nss_status |
6b083d46 | 133 | internal_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 | ||
165 | enum 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 | ||
180 | enum 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 | ||
233 | enum 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 | } |