17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*cb5caa98Sdjl  * Common Development and Distribution License (the "License").
6*cb5caa98Sdjl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*cb5caa98Sdjl  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23*cb5caa98Sdjl  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  *
25*cb5caa98Sdjl  * files/getservent.c -- "files" backend for nsswitch "services" database
267c478bd9Sstevel@tonic-gate  */
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate #include <netdb.h>
317c478bd9Sstevel@tonic-gate #include "files_common.h"
327c478bd9Sstevel@tonic-gate #include <sys/types.h>
337c478bd9Sstevel@tonic-gate #include <netinet/in.h>
34*cb5caa98Sdjl #include <inttypes.h>
357c478bd9Sstevel@tonic-gate #include <strings.h>
36*cb5caa98Sdjl #include <ctype.h>
37*cb5caa98Sdjl #include <stdlib.h>
387c478bd9Sstevel@tonic-gate 
397c478bd9Sstevel@tonic-gate static int
check_name(nss_XbyY_args_t * argp,const char * line,int linelen)40*cb5caa98Sdjl check_name(nss_XbyY_args_t *argp, const char *line, int linelen)
417c478bd9Sstevel@tonic-gate {
42*cb5caa98Sdjl 	const char	*limit, *linep, *keyp;
43*cb5caa98Sdjl 	int		name_match = 0;
447c478bd9Sstevel@tonic-gate 
45*cb5caa98Sdjl 	linep = line;
46*cb5caa98Sdjl 	limit = line + linelen;
47*cb5caa98Sdjl 	keyp = argp->key.serv.serv.name;
48*cb5caa98Sdjl 
49*cb5caa98Sdjl 	/* compare name */
50*cb5caa98Sdjl 	while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) {
51*cb5caa98Sdjl 		keyp++;
52*cb5caa98Sdjl 		linep++;
537c478bd9Sstevel@tonic-gate 	}
54*cb5caa98Sdjl 	if (*keyp == '\0' && linep < limit && isspace(*linep)) {
55*cb5caa98Sdjl 		if (argp->key.serv.proto == NULL)
56*cb5caa98Sdjl 			return (1);
57*cb5caa98Sdjl 		else
58*cb5caa98Sdjl 			name_match = 1;
597c478bd9Sstevel@tonic-gate 	}
60*cb5caa98Sdjl 
61*cb5caa98Sdjl 	/* skip remainder of the name, if any */
62*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep))
63*cb5caa98Sdjl 		linep++;
64*cb5caa98Sdjl 	/* skip the delimiting spaces */
65*cb5caa98Sdjl 	while (linep < limit && isspace(*linep))
66*cb5caa98Sdjl 		linep++;
67*cb5caa98Sdjl 	/* skip port number */
68*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep) && *linep != '/')
69*cb5caa98Sdjl 		linep++;
70*cb5caa98Sdjl 	if (linep == limit || *linep != '/')
71*cb5caa98Sdjl 		return (0);
72*cb5caa98Sdjl 
73*cb5caa98Sdjl 	linep++;
74*cb5caa98Sdjl 	if ((keyp = argp->key.serv.proto) == NULL) {
75*cb5caa98Sdjl 		/* skip protocol */
76*cb5caa98Sdjl 		while (linep < limit && !isspace(*linep))
77*cb5caa98Sdjl 			linep++;
78*cb5caa98Sdjl 	} else {
79*cb5caa98Sdjl 		/* compare protocol */
80*cb5caa98Sdjl 		while (*keyp && linep < limit && !isspace(*linep) &&
81*cb5caa98Sdjl 				*keyp == *linep) {
82*cb5caa98Sdjl 			keyp++;
83*cb5caa98Sdjl 			linep++;
84*cb5caa98Sdjl 		}
85*cb5caa98Sdjl 		/* no protocol match */
86*cb5caa98Sdjl 		if (*keyp || (linep < limit && !isspace(*linep)))
87*cb5caa98Sdjl 			return (0);
88*cb5caa98Sdjl 		/* protocol and name match, return */
89*cb5caa98Sdjl 		if (name_match)
907c478bd9Sstevel@tonic-gate 			return (1);
91*cb5caa98Sdjl 		/* protocol match but name yet to be matched, so continue */
92*cb5caa98Sdjl 	}
93*cb5caa98Sdjl 
94*cb5caa98Sdjl 	/* compare with the aliases */
95*cb5caa98Sdjl 	while (linep < limit) {
96*cb5caa98Sdjl 		/* skip the delimiting spaces */
97*cb5caa98Sdjl 		while (linep < limit && isspace(*linep))
98*cb5caa98Sdjl 			linep++;
99*cb5caa98Sdjl 
100*cb5caa98Sdjl 		/* compare with the alias name */
101*cb5caa98Sdjl 		keyp = argp->key.serv.serv.name;
102*cb5caa98Sdjl 		while (*keyp && linep < limit && !isspace(*linep) &&
103*cb5caa98Sdjl 				*keyp == *linep) {
104*cb5caa98Sdjl 			keyp++;
105*cb5caa98Sdjl 			linep++;
1067c478bd9Sstevel@tonic-gate 		}
107*cb5caa98Sdjl 		if (*keyp == '\0' && (linep == limit || isspace(*linep)))
108*cb5caa98Sdjl 				return (1);
109*cb5caa98Sdjl 
110*cb5caa98Sdjl 		/* skip remainder of the alias name, if any */
111*cb5caa98Sdjl 		while (linep < limit && !isspace(*linep))
112*cb5caa98Sdjl 			linep++;
1137c478bd9Sstevel@tonic-gate 	}
1147c478bd9Sstevel@tonic-gate 	return (0);
1157c478bd9Sstevel@tonic-gate }
1167c478bd9Sstevel@tonic-gate 
1177c478bd9Sstevel@tonic-gate static nss_status_t
getbyname(be,a)1187c478bd9Sstevel@tonic-gate getbyname(be, a)
1197c478bd9Sstevel@tonic-gate 	files_backend_ptr_t	be;
1207c478bd9Sstevel@tonic-gate 	void			*a;
1217c478bd9Sstevel@tonic-gate {
122*cb5caa98Sdjl 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate 	return (_nss_files_XY_all(be, argp, 1,
1257c478bd9Sstevel@tonic-gate 				argp->key.serv.serv.name, check_name));
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate static int
check_port(nss_XbyY_args_t * argp,const char * line,int linelen)129*cb5caa98Sdjl check_port(nss_XbyY_args_t *argp, const char *line, int linelen)
1307c478bd9Sstevel@tonic-gate {
131*cb5caa98Sdjl 	const char	*limit, *linep, *keyp, *numstart;
132*cb5caa98Sdjl 	int		numlen, s_port;
133*cb5caa98Sdjl 	char		numbuf[12], *numend;
134*cb5caa98Sdjl 
135*cb5caa98Sdjl 	linep = line;
136*cb5caa98Sdjl 	limit = line + linelen;
137*cb5caa98Sdjl 
138*cb5caa98Sdjl 	/* skip name */
139*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep))
140*cb5caa98Sdjl 		linep++;
141*cb5caa98Sdjl 	/* skip the delimiting spaces */
142*cb5caa98Sdjl 	while (linep < limit && isspace(*linep))
143*cb5caa98Sdjl 		linep++;
144*cb5caa98Sdjl 
145*cb5caa98Sdjl 	/* compare port num */
146*cb5caa98Sdjl 	numstart = linep;
147*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep) && *linep != '/')
148*cb5caa98Sdjl 		linep++;
149*cb5caa98Sdjl 	if (linep == limit || *linep != '/')
150*cb5caa98Sdjl 		return (0);
151*cb5caa98Sdjl 	numlen = linep - numstart;
152*cb5caa98Sdjl 	if (numlen == 0 || numlen >= sizeof (numbuf))
153*cb5caa98Sdjl 		return (0);
154*cb5caa98Sdjl 	(void) memcpy(numbuf, numstart, numlen);
155*cb5caa98Sdjl 	numbuf[numlen] = '\0';
156*cb5caa98Sdjl 	s_port = htons((int)strtol(numbuf, &numend, 10));
157*cb5caa98Sdjl 	if (*numend != '\0')
158*cb5caa98Sdjl 		return (0);
159*cb5caa98Sdjl 	if (s_port == argp->key.serv.serv.port) {
160*cb5caa98Sdjl 		if ((keyp = argp->key.serv.proto) == NULL)
161*cb5caa98Sdjl 			return (1);
162*cb5caa98Sdjl 	} else
163*cb5caa98Sdjl 		return (0);
1647c478bd9Sstevel@tonic-gate 
165*cb5caa98Sdjl 	/* compare protocol */
166*cb5caa98Sdjl 	linep++;
167*cb5caa98Sdjl 	while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) {
168*cb5caa98Sdjl 		keyp++;
169*cb5caa98Sdjl 		linep++;
170*cb5caa98Sdjl 	}
171*cb5caa98Sdjl 	return (*keyp == '\0' && (linep == limit || isspace(*linep)));
1727c478bd9Sstevel@tonic-gate }
1737c478bd9Sstevel@tonic-gate 
1747c478bd9Sstevel@tonic-gate static nss_status_t
getbyport(be,a)1757c478bd9Sstevel@tonic-gate getbyport(be, a)
1767c478bd9Sstevel@tonic-gate 	files_backend_ptr_t	be;
1777c478bd9Sstevel@tonic-gate 	void			*a;
1787c478bd9Sstevel@tonic-gate {
179*cb5caa98Sdjl 	nss_XbyY_args_t		*argp	= (nss_XbyY_args_t *)a;
1807c478bd9Sstevel@tonic-gate 	char			portstr[12];
1817c478bd9Sstevel@tonic-gate 
182*cb5caa98Sdjl 	(void) snprintf(portstr, 12, "%d", ntohs(argp->key.serv.serv.port));
1837c478bd9Sstevel@tonic-gate 	return (_nss_files_XY_all(be, argp, 1, portstr, check_port));
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate 
1867c478bd9Sstevel@tonic-gate static files_backend_op_t serv_ops[] = {
1877c478bd9Sstevel@tonic-gate 	_nss_files_destr,
1887c478bd9Sstevel@tonic-gate 	_nss_files_endent,
1897c478bd9Sstevel@tonic-gate 	_nss_files_setent,
1907c478bd9Sstevel@tonic-gate 	_nss_files_getent_netdb,
1917c478bd9Sstevel@tonic-gate 	getbyname,
1927c478bd9Sstevel@tonic-gate 	getbyport
1937c478bd9Sstevel@tonic-gate };
1947c478bd9Sstevel@tonic-gate 
1957c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1967c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_files_services_constr(dummy1,dummy2,dummy3)1977c478bd9Sstevel@tonic-gate _nss_files_services_constr(dummy1, dummy2, dummy3)
1987c478bd9Sstevel@tonic-gate 	const char	*dummy1, *dummy2, *dummy3;
1997c478bd9Sstevel@tonic-gate {
2007c478bd9Sstevel@tonic-gate 	return (_nss_files_constr(serv_ops,
2017c478bd9Sstevel@tonic-gate 				sizeof (serv_ops) / sizeof (serv_ops[0]),
2027c478bd9Sstevel@tonic-gate 				_PATH_SERVICES,
2037c478bd9Sstevel@tonic-gate 				NSS_LINELEN_SERVICES,
2047c478bd9Sstevel@tonic-gate 				NULL));
2057c478bd9Sstevel@tonic-gate }
206