xref: /freebsd/crypto/krb5/src/lib/rpc/getrpcent.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
1 /* lib/rpc/getrpcent.c */
2 /*
3  * Copyright (c) 2010, Oracle America, Inc.
4  *
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  *     * Redistributions of source code must retain the above copyright
11  *       notice, this list of conditions and the following disclaimer.
12  *
13  *     * Redistributions in binary form must reproduce the above copyright
14  *       notice, this list of conditions and the following disclaimer in
15  *       the documentation and/or other materials provided with the
16  *       distribution.
17  *
18  *     * Neither the name of the "Oracle America, Inc." nor the names of
19  *       its contributors may be used to endorse or promote products
20  *       derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23  * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  */
34 
35 #include <stdio.h>
36 #include <sys/types.h>
37 #include <netdb.h>
38 #include <gssrpc/rpc.h>
39 #include <string.h>
40 #include <sys/socket.h>
41 
42 SETRPCENT_TYPE setrpcent (int);
43 ENDRPCENT_TYPE endrpcent (void);
44 
45 /*
46  * Internet version.
47  */
48 struct rpcdata {
49 	FILE	*rpcf;
50 	char	*current;
51 	int	currentlen;
52 	int	stayopen;
53 #define	MAXALIASES	35
54 	char	*rpc_aliases[MAXALIASES];
55 	struct	rpcent rpc;
56 	char	line[BUFSIZ+1];
57 	char	*domain;
58 } *rpcdata;
59 static struct rpcdata *get_rpcdata();
60 
61 static	struct rpcent *interpret();
62 struct	hostent *gethostent();
63 
64 static char RPCDB[] = "/etc/rpc";
65 
66 static struct rpcdata *
get_rpcdata(void)67 get_rpcdata(void)
68 {
69 	struct rpcdata *d = rpcdata;
70 
71 	if (d == 0) {
72 		d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata));
73 		rpcdata = d;
74 	}
75 	return (d);
76 }
77 
78 struct rpcent *
getrpcbynumber(int number)79 getrpcbynumber(int number)
80 {
81 	struct rpcdata *d = get_rpcdata();
82 	struct rpcent *p;
83 	int reason;
84 	char adrstr[16], *val = NULL;
85 	int vallen;
86 
87 	if (d == 0)
88 		return (0);
89 	setrpcent(0);
90 	while (p = getrpcent()) {
91 		if (p->r_number == number)
92 			break;
93 	}
94 	endrpcent();
95 	return (p);
96 }
97 
98 struct rpcent *
getrpcbyname(const char * name)99 getrpcbyname(const char *name)
100 {
101 	struct rpcent *rpc;
102 	char **rp;
103 
104 	setrpcent(0);
105 	while(rpc = getrpcent()) {
106 		if (strcmp(rpc->r_name, name) == 0)
107 			return (rpc);
108 		for (rp = rpc->r_aliases; *rp != NULL; rp++) {
109 			if (strcmp(*rp, name) == 0)
110 				return (rpc);
111 		}
112 	}
113 	endrpcent();
114 	return (NULL);
115 }
116 
setrpcent(int f)117 SETRPCENT_TYPE setrpcent(int f)
118 {
119 	struct rpcdata *d = _rpcdata();
120 
121 	if (d == 0)
122 		return;
123 	if (d->rpcf == NULL) {
124 		d->rpcf = fopen(RPCDB, "r");
125 		if (d->rpcf)
126 		    set_cloexec_file(d->rpcf);
127 	} else
128 		rewind(d->rpcf);
129 	if (d->current)
130 		free(d->current);
131 	d->current = NULL;
132 	d->stayopen |= f;
133 }
134 
endrpcent(void)135 ENDRPCENT_TYPE endrpcent(void)
136 {
137 	struct rpcdata *d = _rpcdata();
138 
139 	if (d == 0)
140 		return;
141 	if (d->current && !d->stayopen) {
142 		free(d->current);
143 		d->current = NULL;
144 	}
145 	if (d->rpcf && !d->stayopen) {
146 		fclose(d->rpcf);
147 		d->rpcf = NULL;
148 	}
149 }
150 
151 struct rpcent *
getrpcent(void)152 getrpcent(void)
153 {
154 	struct rpcent *hp;
155 	int reason;
156 	char *key = NULL, *val = NULL;
157 	int keylen, vallen;
158 	struct rpcdata *d = _rpcdata();
159 
160 	if (d == 0)
161 		return(NULL);
162 	if (d->rpcf == NULL) {
163 	    if ((d->rpcf = fopen(RPCDB, "r")) == NULL)
164 		return (NULL);
165 	    set_cloexec_file(d->rpcf);
166 	}
167 	if (fgets(d->line, BUFSIZ, d->rpcf) == NULL)
168 		return (NULL);
169 	return interpret(d->line, strlen(d->line));
170 }
171 
172 static struct rpcent *
interpret(char * val,int len)173 interpret(char *val, int len)
174 {
175 	struct rpcdata *d = _rpcdata();
176 	char *p;
177 	char *cp, **q;
178 
179 	if (d == 0)
180 		return;
181 	strncpy(d->line, val, len);
182 	p = d->line;
183 	d->line[len] = '\n';
184 	if (*p == '#')
185 		return (getrpcent());
186 	cp = strchr(p, '#');
187 	if (cp == NULL)
188     {
189 		cp = strchr(p, '\n');
190 		if (cp == NULL)
191 			return (getrpcent());
192 	}
193 	*cp = '\0';
194 	cp = strchr(p, ' ');
195 	if (cp == NULL)
196     {
197 		cp = strchr(p, '\t');
198 		if (cp == NULL)
199 			return (getrpcent());
200 	}
201 	*cp++ = '\0';
202 	/* THIS STUFF IS INTERNET SPECIFIC */
203 	d->rpc.r_name = d->line;
204 	while (*cp == ' ' || *cp == '\t')
205 		cp++;
206 	d->rpc.r_number = atoi(cp);
207 	q = d->rpc.r_aliases = d->rpc_aliases;
208 	cp = strchr(p, ' ');
209 	if (cp != NULL)
210 		*cp++ = '\0';
211 	else
212     {
213 		cp = strchr(p, '\t');
214 		if (cp != NULL)
215 			*cp++ = '\0';
216 	}
217 	while (cp && *cp) {
218 		if (*cp == ' ' || *cp == '\t') {
219 			cp++;
220 			continue;
221 		}
222 		if (q < &(d->rpc_aliases[MAXALIASES - 1]))
223 			*q++ = cp;
224 		cp = strchr(p, ' ');
225 		if (cp != NULL)
226 			*cp++ = '\0';
227 		else
228 	    {
229 			cp = strchr(p, '\t');
230 			if (cp != NULL)
231 				*cp++ = '\0';
232 		}
233 	}
234 	*q = NULL;
235 	return (&d->rpc);
236 }
237