]> git.ipfire.org Git - thirdparty/glibc.git/blame - nis/nss_nisplus/nisplus-ethers.c
Update.
[thirdparty/glibc.git] / nis / nss_nisplus / nisplus-ethers.c
CommitLineData
e61abf83
UD
1/* Copyright (C) 1997 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
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
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
19
20#include <nss.h>
21#include <errno.h>
22#include <ctype.h>
23#include <string.h>
5107cf1d 24#include <bits/libc-lock.h>
e61abf83
UD
25#include <netdb.h>
26#include <netinet/ether.h>
27#include <rpcsvc/nis.h>
e61abf83
UD
28#include <netinet/if_ether.h>
29
30#include "nss-nisplus.h"
31
32__libc_lock_define_initialized (static, lock)
33
34static nis_result *result = NULL;
2d7da676
UD
35static nis_name tablename_val = NULL;
36static u_long tablename_len = 0;
e61abf83
UD
37
38/* Because the `ethers' lookup does not fit so well in the scheme so
39 we define a dummy struct here which helps us to use the available
40 functions. */
41struct etherent
42{
43 const char *e_name;
44 struct ether_addr e_addr;
45};
46struct etherent_data {};
47
e61abf83
UD
48#define NISENTRYVAL(idx,col,res) \
49 ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_val)
50
51#define NISENTRYLEN(idx,col,res) \
52 ((res)->objects.objects_val[(idx)].zo_data.objdata_u.en_data.en_cols.en_cols_val[(col)].ec_value.ec_value_len)
53
54static int
55_nss_nisplus_parse_etherent (nis_result *result, struct etherent *ether,
d71b808a 56 char *buffer, size_t buflen, int *errnop)
e61abf83
UD
57{
58 char *p = buffer;
59 size_t room_left = buflen;
e61abf83
UD
60
61 if (result == NULL)
26dee9c4 62 return 0;
e61abf83 63
d71b808a
UD
64 if ((result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS)
65 || result->objects.objects_len != 1
66 || __type_of (NIS_RES_OBJECT (result)) != NIS_ENTRY_OBJ
67 || strcmp (NIS_RES_OBJECT (result)->EN_data.en_type,
68 "ethers_tbl") != 0
69 || NIS_RES_OBJECT (result)->EN_data.en_cols.en_cols_len < 2)
26dee9c4 70 return 0;
e61abf83 71
e61abf83
UD
72 /* Generate the ether entry format and use the normal parser */
73 if (NISENTRYLEN (0, 0, result) +1 > room_left)
74 {
d71b808a 75 *errnop = ERANGE;
60c96635 76 return -1;
e61abf83
UD
77 }
78 strncpy (p, NISENTRYVAL (0, 0, result), NISENTRYLEN (0, 0, result));
79 room_left -= (NISENTRYLEN (0, 0, result) +1);
2d7da676
UD
80 ether->e_name = p;
81
82 ether->e_addr = *ether_aton (NISENTRYVAL (0, 1, result));
83
84 return 1;
85}
e61abf83 86
2d7da676 87static enum nss_status
d71b808a 88_nss_create_tablename (int *errnop)
2d7da676
UD
89{
90 if (tablename_val == NULL)
e61abf83 91 {
2d7da676
UD
92 char buf [40 + strlen (nis_local_directory ())];
93 char *p;
e61abf83 94
9a0a462c
UD
95 p = __stpcpy (buf, "ethers.org_dir.");
96 p = __stpcpy (p, nis_local_directory ());
97 tablename_val = __strdup (buf);
2d7da676 98 if (tablename_val == NULL)
d71b808a
UD
99 {
100 *errnop = errno;
101 return NSS_STATUS_TRYAGAIN;
102 }
2d7da676
UD
103 tablename_len = strlen (tablename_val);
104 }
105 return NSS_STATUS_SUCCESS;
e61abf83
UD
106}
107
2d7da676 108
e61abf83
UD
109enum nss_status
110_nss_nisplus_setetherent (void)
111{
2d7da676 112 enum nss_status status;
d71b808a 113 int err;
2d7da676
UD
114
115 status = NSS_STATUS_SUCCESS;
116
e61abf83
UD
117 __libc_lock_lock (lock);
118
119 if (result)
120 nis_freeresult (result);
121 result = NULL;
2d7da676 122
d71b808a 123 if (_nss_create_tablename (&err) != NSS_STATUS_SUCCESS)
2d7da676 124 status = NSS_STATUS_UNAVAIL;
e61abf83
UD
125
126 __libc_lock_unlock (lock);
127
128 return NSS_STATUS_SUCCESS;
129}
130
131enum nss_status
132_nss_nisplus_endetherent (void)
133{
134 __libc_lock_lock (lock);
135
136 if (result)
137 nis_freeresult (result);
138 result = NULL;
e61abf83
UD
139
140 __libc_lock_unlock (lock);
141
142 return NSS_STATUS_SUCCESS;
143}
144
145static enum nss_status
146internal_nisplus_getetherent_r (struct etherent *ether, char *buffer,
d71b808a 147 size_t buflen, int *errnop)
e61abf83
UD
148{
149 int parse_res;
150
2d7da676 151 if (tablename_val == NULL)
d71b808a
UD
152 {
153 enum nss_status status = _nss_create_tablename (errnop);
154
155 if (status != NSS_STATUS_SUCCESS)
156 return status;
157 }
2d7da676 158
e61abf83
UD
159 /* Get the next entry until we found a correct one. */
160 do
161 {
60c96635 162 nis_result *saved_result;
8f2ece69 163
e61abf83
UD
164 if (result == NULL)
165 {
60c96635 166 saved_result = NULL;
d71b808a 167 result = nis_first_entry (tablename_val);
e61abf83
UD
168 if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
169 return niserr2nss (result->status);
170 }
171 else
172 {
173 nis_result *res2;
174
2d7da676 175 res2 = nis_next_entry(tablename_val, &result->cookie);
60c96635 176 saved_result = result;
e61abf83
UD
177 result = res2;
178 if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
60c96635
UD
179 {
180 nis_freeresult (saved_result);
181 return niserr2nss (result->status);
182 }
e61abf83
UD
183 }
184
d71b808a
UD
185 parse_res = _nss_nisplus_parse_etherent (result, ether, buffer,
186 buflen, errnop);
187 if (parse_res == -1)
60c96635
UD
188 {
189 nis_freeresult (result);
d71b808a 190 *errnop = ERANGE;
60c96635
UD
191 result = saved_result;
192 return NSS_STATUS_TRYAGAIN;
193 }
194 else
195 {
196 if (saved_result != NULL)
197 nis_freeresult (saved_result);
198 }
8f2ece69 199
e61abf83
UD
200 } while (!parse_res);
201
202 return NSS_STATUS_SUCCESS;
203}
204
205enum nss_status
206_nss_nisplus_getetherent_r (struct etherent *result, char *buffer,
d71b808a 207 size_t buflen, int *errnop)
e61abf83
UD
208{
209 int status;
210
211 __libc_lock_lock (lock);
212
d71b808a 213 status = internal_nisplus_getetherent_r (result, buffer, buflen, errnop);
e61abf83
UD
214
215 __libc_lock_unlock (lock);
216
217 return status;
218}
219
220enum nss_status
221_nss_nisplus_gethostton_r (const char *name, struct etherent *eth,
d71b808a 222 char *buffer, size_t buflen, int *errnop)
e61abf83
UD
223{
224 int parse_res;
225
2d7da676 226 if (tablename_val == NULL)
d71b808a
UD
227 {
228 enum nss_status status = _nss_create_tablename (errnop);
229
230 if (status != NSS_STATUS_SUCCESS)
231 return status;
232 }
2d7da676 233
60c96635 234 if (name != NULL)
e61abf83
UD
235 {
236 nis_result *result;
2d7da676 237 char buf[strlen (name) + 40 + tablename_len];
e61abf83 238
d71b808a 239 sprintf (buf, "[name=%s],%s", name, tablename_val);
e61abf83 240
d71b808a 241 result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
e61abf83
UD
242
243 if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
60c96635
UD
244 {
245 enum nss_status status = niserr2nss (result->status);
246 nis_freeresult (result);
247 return status;
248 }
8f2ece69 249
d71b808a
UD
250 parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
251 buflen, errnop);
252 if (parse_res == -1)
60c96635
UD
253 {
254 nis_freeresult (result);
d71b808a 255 *errnop = ERANGE;
60c96635
UD
256 return NSS_STATUS_TRYAGAIN;
257 }
8f2ece69 258
e61abf83
UD
259 if (parse_res)
260 return NSS_STATUS_SUCCESS;
e61abf83 261 }
60c96635 262 return NSS_STATUS_NOTFOUND;
e61abf83
UD
263}
264
265enum nss_status
266_nss_nisplus_getntohost_r (const struct ether_addr *addr,
267 struct etherent *eth,
d71b808a 268 char *buffer, size_t buflen, int *errnop)
e61abf83 269{
2d7da676 270 if (tablename_val == NULL)
d71b808a
UD
271 {
272 enum nss_status status = _nss_create_tablename (errnop);
273
274 if (status != NSS_STATUS_SUCCESS)
275 return status;
276 }
e61abf83
UD
277
278 if (addr == NULL)
279 {
d71b808a 280 *errnop = EINVAL;
e61abf83
UD
281 return NSS_STATUS_UNAVAIL;
282 }
2d7da676
UD
283 else
284 {
285 int parse_res;
286 nis_result *result;
287 char buf[255 + tablename_len];
e61abf83 288
2d7da676 289 memset (&buf, '\0', sizeof (buf));
d71b808a
UD
290 sprintf (buf, "[addr=%x:%x:%x:%x:%x:%x],ethers.org_dir",
291 addr->ether_addr_octet[0], addr->ether_addr_octet[1],
292 addr->ether_addr_octet[2], addr->ether_addr_octet[3],
293 addr->ether_addr_octet[4], addr->ether_addr_octet[5]);
e61abf83 294
d71b808a 295 result = nis_list (buf, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL);
e61abf83 296
2d7da676 297 if (niserr2nss (result->status) != NSS_STATUS_SUCCESS)
60c96635
UD
298 {
299 enum nss_status status = niserr2nss (result->status);
300 nis_freeresult (result);
301 return status;
302 }
e61abf83 303
d71b808a
UD
304 parse_res = _nss_nisplus_parse_etherent (result, eth, buffer,
305 buflen, errnop);
306 if (parse_res == -1)
60c96635
UD
307 {
308 nis_freeresult (result);
d71b808a 309 *errnop = ERANGE;
60c96635
UD
310 return NSS_STATUS_TRYAGAIN;
311 }
8f2ece69 312
2d7da676
UD
313 if (parse_res)
314 return NSS_STATUS_SUCCESS;
2d7da676 315 }
60c96635 316 return NSS_STATUS_NOTFOUND;
e61abf83 317}