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