]> git.ipfire.org Git - thirdparty/glibc.git/blame - nis/nss_nisplus/nisplus-ethers.c
nis/nss_nisplus: Kill warnings
[thirdparty/glibc.git] / nis / nss_nisplus / nisplus-ethers.c
CommitLineData
1a544854 1/* Copyright (C) 1997,1998,2000-2003,2005,2006,2007,2011
697d37b1 2 Free Software Foundation, Inc.
e61abf83 3 This file is part of the GNU C Library.
ed073f0e 4 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997.
e61abf83
UD
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
e61abf83
UD
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 14 Lesser General Public License for more details.
e61abf83 15
41bdb6e2
AJ
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
e61abf83 20
636e689e 21#include <atomic.h>
a334319f 22#include <ctype.h>
636e689e
UD
23#include <errno.h>
24#include <inttypes.h>
a334319f 25#include <netdb.h>
636e689e
UD
26#include <nss.h>
27#include <string.h>
e61abf83 28#include <netinet/ether.h>
a334319f 29#include <netinet/if_ether.h>
636e689e
UD
30#include <rpcsvc/nis.h>
31#include <bits/libc-lock.h>
e61abf83
UD
32
33#include "nss-nisplus.h"
34
35__libc_lock_define_initialized (static, lock)
36
fc9f33e3
UD
37static nis_result *result;
38static nis_name tablename_val;
39static u_long tablename_len;
e61abf83 40
e61abf83 41
1620084c 42#define NISENTRYVAL(idx, col, res) \
1a544854 43 (NIS_RES_OBJECT (res)[idx].zo_data.objdata_u.en_data.en_cols.en_cols_val[col].ec_value.ec_value_val)
e61abf83 44
1620084c 45#define NISENTRYLEN(idx, col, res) \
1a544854 46 (NIS_RES_OBJECT (res)[idx].zo_data.objdata_u.en_data.en_cols.en_cols_val[col].ec_value.ec_value_len)
e61abf83
UD
47
48static int
49_nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
6b083d46 50 char *buffer, size_t buflen, int *errnop)
e61abf83
UD
51{
52 char *p = buffer;
53 size_t room_left = buflen;
e61abf83
UD
54
55 if (result == NULL)
26dee9c4 56 return 0;
e61abf83 57
d71b808a 58 if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
1620084c 59 || NIS_RES_NUMOBJ (result) != 1
d71b808a
UD
60 || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
61 || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
62 "ethers_tbl") != 0
63 || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 2)
26dee9c4 64 return 0;
e61abf83 65
e61abf83 66 /* Generate the ether entry format and use the normal parser */
1620084c 67 if (NISENTRYLEN (0, 0, result) + 1 > room_left)
e61abf83 68 {
d71b808a 69 *errnop = ERANGE;
60c96635 70 return -1;
e61abf83 71 }
1620084c
UD
72 char *cp = __stpncpy (p, NISENTRYVAL (0, 0, result),
73 NISENTRYLEN (0, 0, result));
74 *cp = '\0';
75 room_left -= NISENTRYLEN (0, 0, result) + 1;
2d7da676
UD
76 ether->e_name = p;
77
636e689e
UD
78 struct ether_addr *ea = ether_aton (NISENTRYVAL (0, 1, result));
79 if (ea == NULL)
80 {
81 *errnop = EINVAL;
82 return -2;
83 }
84
85 ether->e_addr = *ea;
2d7da676
UD
86
87 return 1;
88}
e61abf83 89
2d7da676 90static enum nss_status
d71b808a 91_nss_create_tablename (int *errnop)
2d7da676
UD
92{
93 if (tablename_val == NULL)
e61abf83 94 {
636e689e
UD
95 const char *local_dir = nis_local_directory ();
96 size_t local_dir_len = strlen (local_dir);
97 static const char prefix[] = "ethers.org_dir.";
e61abf83 98
636e689e 99 char *p = malloc (sizeof (prefix) + local_dir_len);
c8e82b4a 100 if (p == NULL)
d71b808a
UD
101 {
102 *errnop = errno;
103 return NSS_STATUS_TRYAGAIN;
104 }
636e689e
UD
105
106 memcpy (__stpcpy (p, prefix), local_dir, local_dir_len + 1);
107
108 tablename_len = sizeof (prefix) - 1 + local_dir_len;
109
110 atomic_write_barrier ();
111
112 tablename_val = p;
2d7da676
UD
113 }
114 return NSS_STATUS_SUCCESS;
e61abf83
UD
115}
116
2d7da676 117
e61abf83 118enum nss_status
ed073f0e 119_nss_nisplus_setetherent (int stayopen)
e61abf83 120{
2d7da676 121 enum nss_status status;
d71b808a 122 int err;
2d7da676
UD
123
124 status = NSS_STATUS_SUCCESS;
125
e61abf83
UD
126 __libc_lock_lock (lock);
127
636e689e
UD
128 if (result != NULL)
129 {
130 nis_freeresult (result);
131 result = NULL;
132 }
2d7da676 133
d71b808a 134 if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
2d7da676 135 status = NSS_STATUS_UNAVAIL;
e61abf83
UD
136
137 __libc_lock_unlock (lock);
138
1a544854 139 return status;
e61abf83
UD
140}
141
142enum nss_status
143_nss_nisplus_endetherent (void)
144{
145 __libc_lock_lock (lock);
146
636e689e
UD
147 if (result != NULL)
148 {
149 nis_freeresult (result);
150 result = NULL;
151 }
e61abf83
UD
152
153 __libc_lock_unlock (lock);
154
155 return NSS_STATUS_SUCCESS;
156}
157
158static enum nss_status
159internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
d71b808a 160 size_t buflen, int *errnop)
e61abf83 161{
2d7da676 162 if (tablename_val == NULL)
d71b808a
UD
163 {
164 enum nss_status status = _nss_create_tablename (errnop);
165
166 if (status != NSS_STATUS_SUCCESS)
167 return status;
168 }
2d7da676 169
e61abf83 170 /* Get the next entry until we found a correct one. */
8e64faef 171 int parse_res;
e61abf83
UD
172 do
173 {
60c96635 174 nis_result *saved_result;
8f2ece69 175
e61abf83
UD
176 if (result == NULL)
177 {
60c96635 178 saved_result = NULL;
d71b808a 179 result = nis_first_entry (tablename_val);
487609e3
UD
180 if (result == NULL)
181 {
182 *errnop = errno;
183 return NSS_STATUS_TRYAGAIN;
184 }
e61abf83
UD
185 if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
186 return niserr2nss (result->status);
187 }
188 else
189 {
60c96635 190 saved_result = result;
8e64faef 191 result = nis_next_entry (tablename_val, &result->cookie);
487609e3
UD
192 if (result == NULL)
193 {
194 *errnop = errno;
195 return NSS_STATUS_TRYAGAIN;
196 }
e61abf83 197 if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
60c96635
UD
198 {
199 nis_freeresult (saved_result);
200 return niserr2nss (result->status);
201 }
e61abf83
UD
202 }
203
d71b808a
UD
204 parse_res = _nss_nisplus_parse_etherent (result, ether, buffer,
205 buflen, errnop);
206 if (parse_res == -1)
60c96635
UD
207 {
208 nis_freeresult (result);
209 result = saved_result;
210 return NSS_STATUS_TRYAGAIN;
211 }
8f2ece69 212
8e64faef
UD
213 if (saved_result != NULL)
214 nis_freeresult (saved_result);
215
216 }
217 while (!parse_res);
e61abf83
UD
218
219 return NSS_STATUS_SUCCESS;
220}
221
222enum nss_status
223_nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
d71b808a 224 size_t buflen, int *errnop)
e61abf83
UD
225{
226 int status;
227
228 __libc_lock_lock (lock);
229
d71b808a 230 status = internal_nisplus_getetherent_r (result, buffer, buflen, errnop);
e61abf83
UD
231
232 __libc_lock_unlock (lock);
233
234 return status;
235}
236
237enum nss_status
238_nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
d71b808a 239 char *buffer, size_t buflen, int *errnop)
e61abf83 240{
2d7da676 241 if (tablename_val == NULL)
d71b808a
UD
242 {
243 enum nss_status status = _nss_create_tablename (errnop);
244
245 if (status != NSS_STATUS_SUCCESS)
246 return status;
247 }
2d7da676 248
4b1fef84 249 if (name == NULL)
ac9f45cf
UD
250 {
251 *errnop = EINVAL;
252 return NSS_STATUS_UNAVAIL;
253 }
0ecb606c 254
8e64faef
UD
255 char buf[strlen (name) + 9 + tablename_len];
256 int olderr = errno;
0ecb606c 257
8e64faef 258 snprintf (buf, sizeof (buf), "[name=%s],%s", name, tablename_val);
34816665 259
697d37b1
JJ
260 nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
261 NULL, NULL);
0ecb606c 262
8e64faef
UD
263 if (result == NULL)
264 {
265 *errnop = ENOMEM;
266 return NSS_STATUS_TRYAGAIN;
267 }
268
269 if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
270 {
271 enum nss_status status = niserr2nss (result->status);
272 nis_freeresult (result);
273 return status;
274 }
275
276 int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
a334319f 277 buflen, errnop);
0292b0dd
UD
278
279 /* We do not need the lookup result anymore. */
280 nis_freeresult (result);
281
8e64faef
UD
282 if (__builtin_expect (parse_res < 1, 0))
283 {
284 __set_errno (olderr);
0ecb606c 285
8e64faef 286 if (parse_res == -1)
0292b0dd
UD
287 return NSS_STATUS_TRYAGAIN;
288
289 return NSS_STATUS_NOTFOUND;
e61abf83 290 }
8e64faef
UD
291
292 return NSS_STATUS_SUCCESS;
e61abf83
UD
293}
294
295enum nss_status
8e64faef 296_nss_nisplus_getntohost_r (const struct ether_addr *addr, struct etherent *eth,
d71b808a 297 char *buffer, size_t buflen, int *errnop)
e61abf83 298{
2d7da676 299 if (tablename_val == NULL)
d71b808a 300 {
636e689e
UD
301 __libc_lock_lock (lock);
302
d71b808a
UD
303 enum nss_status status = _nss_create_tablename (errnop);
304
636e689e
UD
305 __libc_lock_unlock (lock);
306
d71b808a
UD
307 if (status != NSS_STATUS_SUCCESS)
308 return status;
309 }
e61abf83
UD
310
311 if (addr == NULL)
312 {
d71b808a 313 *errnop = EINVAL;
e61abf83
UD
314 return NSS_STATUS_UNAVAIL;
315 }
e61abf83 316
636e689e 317 char buf[26 + tablename_len];
0ecb606c 318
636e689e
UD
319 snprintf (buf, sizeof (buf),
320 "[addr=%" PRIx8 ":%" PRIx8 ":%" PRIx8 ":%" PRIx8 ":%" PRIx8
321 ":%" PRIx8 "],%s",
322 addr->ether_addr_octet[0], addr->ether_addr_octet[1],
323 addr->ether_addr_octet[2], addr->ether_addr_octet[3],
324 addr->ether_addr_octet[4], addr->ether_addr_octet[5],
325 tablename_val);
0ecb606c 326
697d37b1
JJ
327 nis_result *result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS | USE_DGRAM,
328 NULL, NULL);
636e689e
UD
329
330 if (result == NULL)
331 {
332 *errnop = ENOMEM;
333 return NSS_STATUS_TRYAGAIN;
334 }
335
336 if (__builtin_expect (niserr2nss (result->status) != NSS_STATUS_SUCCESS, 0))
337 {
338 enum nss_status status = niserr2nss (result->status);
339 nis_freeresult (result);
340 return status;
341 }
342
8e64faef
UD
343 int parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
344 buflen, errnop);
0292b0dd
UD
345
346 /* We do not need the lookup result anymore. */
347 nis_freeresult (result);
348
636e689e
UD
349 if (__builtin_expect (parse_res < 1, 0))
350 {
351 if (parse_res == -1)
0292b0dd 352 return NSS_STATUS_TRYAGAIN;
0ecb606c 353
636e689e 354 return NSS_STATUS_NOTFOUND;
2d7da676 355 }
636e689e
UD
356
357 return NSS_STATUS_SUCCESS;
e61abf83 358}