]> git.ipfire.org Git - thirdparty/glibc.git/blame - nis/nss_nis/nis-rpc.c
Use <> for include of kernel-features.h.
[thirdparty/glibc.git] / nis / nss_nis / nis-rpc.c
CommitLineData
ab9a9ff8
UD
1/* Copyright (C) 1996-1998,2000,2002,2003,2004,2006
2 Free Software Foundation, Inc.
6259ec0d 3 This file is part of the GNU C Library.
3b965a7d 4 Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
6259ec0d
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.
6259ec0d
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.
6259ec0d 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. */
6259ec0d
UD
20
21#include <nss.h>
22#include <netdb.h>
23#include <ctype.h>
24#include <errno.h>
25#include <string.h>
5107cf1d 26#include <bits/libc-lock.h>
6259ec0d
UD
27#include <rpcsvc/yp.h>
28#include <rpcsvc/ypclnt.h>
29
30#include "nss-nis.h"
31
7e3be507
UD
32/* Get the declaration of the parser function. */
33#define ENTNAME rpcent
34#define EXTERN_PARSER
cf29ffbe 35#include <nss/nss_files/files-parse.c>
7e3be507 36
6259ec0d
UD
37__libc_lock_define_initialized (static, lock)
38
e0d4e91d 39static intern_t intern;
0ecb606c 40
a334319f
UD
41
42static void
43internal_nis_endrpcent (intern_t *intern)
44{
e0d4e91d
UD
45 struct response_t *curr = intern->next;
46
47 while (curr != NULL)
a334319f 48 {
e0d4e91d
UD
49 struct response_t *last = curr;
50 curr = curr->next;
51 free (last);
a334319f 52 }
e0d4e91d
UD
53
54 intern->next = intern->start = NULL;
b677d674
UD
55}
56
6259ec0d 57static enum nss_status
f166d865 58internal_nis_setrpcent (intern_t *intern)
6259ec0d 59{
f166d865
UD
60 char *domainname;
61 struct ypall_callback ypcb;
0d8733c4 62 enum nss_status status;
cf29ffbe 63
f166d865
UD
64 if (yp_get_default_domain (&domainname))
65 return NSS_STATUS_UNAVAIL;
cf29ffbe 66
b677d674 67 internal_nis_endrpcent (intern);
f166d865 68
e0d4e91d
UD
69 ypcb.foreach = _nis_saveit;
70 ypcb.data = (char *) intern;
71 status = yperr2nss (yp_all (domainname, "rpc.bynumber", &ypcb));
72
73 /* Mark the last buffer as full. */
74 if (intern->next != NULL)
75 intern->next->size = intern->offset;
76
f166d865 77 intern->next = intern->start;
e0d4e91d 78 intern->offset = 0;
f166d865 79
0d8733c4 80 return status;
6259ec0d
UD
81}
82
83enum nss_status
23bab906 84_nss_nis_setrpcent (int stayopen)
6259ec0d
UD
85{
86 enum nss_status status;
87
88 __libc_lock_lock (lock);
89
90 status = internal_nis_setrpcent (&intern);
91
92 __libc_lock_unlock (lock);
93
94 return status;
95}
96
6259ec0d
UD
97enum nss_status
98_nss_nis_endrpcent (void)
99{
6259ec0d
UD
100 __libc_lock_lock (lock);
101
b677d674 102 internal_nis_endrpcent (&intern);
6259ec0d
UD
103
104 __libc_lock_unlock (lock);
105
b677d674 106 return NSS_STATUS_SUCCESS;
6259ec0d
UD
107}
108
109static enum nss_status
110internal_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
e0d4e91d 111 int *errnop, intern_t *intern)
6259ec0d 112{
7e3be507 113 struct parser_data *pdata = (void *) buffer;
f166d865 114 int parse_res;
6259ec0d 115 char *p;
cf29ffbe 116
e0d4e91d
UD
117 if (intern->start == NULL)
118 internal_nis_setrpcent (intern);
cf29ffbe 119
ed3691ba
UD
120 if (intern->next == NULL)
121 /* Not one entry in the map. */
122 return NSS_STATUS_NOTFOUND;
123
6259ec0d
UD
124 /* Get the next entry until we found a correct one. */
125 do
126 {
e0d4e91d
UD
127 struct response_t *bucket = intern->next;
128
129 if (__builtin_expect (intern->offset >= bucket->size, 0))
130 {
131 if (bucket->next == NULL)
132 return NSS_STATUS_NOTFOUND;
133
134 /* We look at all the content in the current bucket. Go on
135 to the next. */
136 bucket = intern->next = bucket->next;
137 intern->offset = 0;
138 }
139
140 for (p = &bucket->mem[intern->offset]; isspace (*p); ++p)
141 ++intern->offset;
0ecb606c 142
e0d4e91d
UD
143 size_t len = strlen (p) + 1;
144 if (__builtin_expect (len > buflen, 0))
145 {
146 *errnop = ERANGE;
147 return NSS_STATUS_TRYAGAIN;
148 }
149
150 /* We unfortunately have to copy the data in the user-provided
151 buffer because that buffer might be around for a very long
152 time and the servent structure must remain valid. If we would
153 rely on the BUCKET memory the next 'setservent' or 'endservent'
154 call would destroy it.
155
156 The important thing is that it is a single NUL-terminated
157 string. This is what the parsing routine expects. */
158 p = memcpy (buffer, &bucket->mem[intern->offset], len);
cf29ffbe 159
d71b808a 160 parse_res = _nss_files_parse_rpcent (p, rpc, pdata, buflen, errnop);
ab9a9ff8 161 if (__builtin_expect (parse_res == -1, 0))
6259ec0d 162 return NSS_STATUS_TRYAGAIN;
e0d4e91d
UD
163
164 intern->offset += len;
6259ec0d
UD
165 }
166 while (!parse_res);
cf29ffbe 167
6259ec0d
UD
168 return NSS_STATUS_SUCCESS;
169}
170
171enum nss_status
d71b808a
UD
172_nss_nis_getrpcent_r (struct rpcent *rpc, char *buffer, size_t buflen,
173 int *errnop)
6259ec0d
UD
174{
175 enum nss_status status;
176
177 __libc_lock_lock (lock);
178
d71b808a 179 status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop, &intern);
6259ec0d
UD
180
181 __libc_lock_unlock (lock);
182
183 return status;
184}
185
186enum nss_status
187_nss_nis_getrpcbyname_r (const char *name, struct rpcent *rpc,
d71b808a 188 char *buffer, size_t buflen, int *errnop)
6259ec0d 189{
6259ec0d
UD
190 if (name == NULL)
191 {
ac9f45cf 192 *errnop = EINVAL;
6259ec0d
UD
193 return NSS_STATUS_UNAVAIL;
194 }
195
e0d4e91d 196 intern_t data = { NULL, NULL, 0 };
ab9a9ff8
UD
197 enum nss_status status = internal_nis_setrpcent (&data);
198 if (__builtin_expect (status != NSS_STATUS_SUCCESS, 0))
6259ec0d
UD
199 return status;
200
ab9a9ff8 201 int found = 0;
6259ec0d 202 while (!found &&
d71b808a
UD
203 ((status = internal_nis_getrpcent_r (rpc, buffer, buflen, errnop,
204 &data)) == NSS_STATUS_SUCCESS))
6259ec0d
UD
205 {
206 if (strcmp (rpc->r_name, name) == 0)
207 found = 1;
208 else
209 {
210 int i = 0;
211
212 while (rpc->r_aliases[i] != NULL)
213 {
214 if (strcmp (rpc->r_aliases[i], name) == 0)
215 {
216 found = 1;
217 break;
218 }
219 else
220 ++i;
221 }
222 }
223 }
224
225 internal_nis_endrpcent (&data);
226
ab9a9ff8 227 if (__builtin_expect (!found && status == NSS_STATUS_SUCCESS, 0))
34816665 228 return NSS_STATUS_NOTFOUND;
ab9a9ff8
UD
229
230 return status;
6259ec0d
UD
231}
232
233enum nss_status
234_nss_nis_getrpcbynumber_r (int number, struct rpcent *rpc,
d71b808a 235 char *buffer, size_t buflen, int *errnop)
6259ec0d 236{
ab9a9ff8
UD
237 char *domain;
238 if (__builtin_expect (yp_get_default_domain (&domain), 0))
6259ec0d
UD
239 return NSS_STATUS_UNAVAIL;
240
ab9a9ff8
UD
241 char buf[32];
242 int nlen = snprintf (buf, sizeof (buf), "%d", number);
6259ec0d 243
ab9a9ff8
UD
244 char *result;
245 int len;
246 int yperr = yp_match (domain, "rpc.bynumber", buf, nlen, &result, &len);
6259ec0d 247
ab9a9ff8 248 if (__builtin_expect (yperr != YPERR_SUCCESS, 0))
6259ec0d 249 {
ab9a9ff8
UD
250 enum nss_status retval = yperr2nss (yperr);
251
34816665 252 if (retval == NSS_STATUS_TRYAGAIN)
d71b808a 253 *errnop = errno;
6259ec0d
UD
254 return retval;
255 }
256
ab9a9ff8 257 if (__builtin_expect ((size_t) (len + 1) > buflen, 0))
6259ec0d
UD
258 {
259 free (result);
d71b808a 260 *errnop = ERANGE;
6259ec0d
UD
261 return NSS_STATUS_TRYAGAIN;
262 }
263
ab9a9ff8 264 char *p = strncpy (buffer, result, len);
6259ec0d
UD
265 buffer[len] = '\0';
266 while (isspace (*p))
267 ++p;
268 free (result);
269
ab9a9ff8
UD
270 int parse_res = _nss_files_parse_rpcent (p, rpc, (void *) buffer, buflen,
271 errnop);
272 if (__builtin_expect (parse_res < 1, 0))
6259ec0d 273 {
60c96635 274 if (parse_res == -1)
6259ec0d
UD
275 return NSS_STATUS_TRYAGAIN;
276 else
34816665 277 return NSS_STATUS_NOTFOUND;
6259ec0d
UD
278 }
279 else
280 return NSS_STATUS_SUCCESS;
281}