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 #include <netdb.h>
297c478bd9Sstevel@tonic-gate #include "files_common.h"
307c478bd9Sstevel@tonic-gate #include <sys/types.h>
317c478bd9Sstevel@tonic-gate #include <netinet/in.h>
32*cb5caa98Sdjl #include <inttypes.h>
337c478bd9Sstevel@tonic-gate #include <strings.h>
34*cb5caa98Sdjl #include <ctype.h>
35*cb5caa98Sdjl #include <stdlib.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate static int
check_name(nss_XbyY_args_t * argp,const char * line,int linelen)38*cb5caa98Sdjl check_name(nss_XbyY_args_t *argp, const char *line, int linelen)
397c478bd9Sstevel@tonic-gate {
40*cb5caa98Sdjl 	const char	*limit, *linep, *keyp;
41*cb5caa98Sdjl 	int		name_match = 0;
427c478bd9Sstevel@tonic-gate 
43*cb5caa98Sdjl 	linep = line;
44*cb5caa98Sdjl 	limit = line + linelen;
45*cb5caa98Sdjl 	keyp = argp->key.serv.serv.name;
46*cb5caa98Sdjl 
47*cb5caa98Sdjl 	/* compare name */
48*cb5caa98Sdjl 	while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) {
49*cb5caa98Sdjl 		keyp++;
50*cb5caa98Sdjl 		linep++;
517c478bd9Sstevel@tonic-gate 	}
52*cb5caa98Sdjl 	if (*keyp == '\0' && linep < limit && isspace(*linep)) {
53*cb5caa98Sdjl 		if (argp->key.serv.proto == NULL)
54*cb5caa98Sdjl 			return (1);
55*cb5caa98Sdjl 		else
56*cb5caa98Sdjl 			name_match = 1;
577c478bd9Sstevel@tonic-gate 	}
58*cb5caa98Sdjl 
59*cb5caa98Sdjl 	/* skip remainder of the name, if any */
60*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep))
61*cb5caa98Sdjl 		linep++;
62*cb5caa98Sdjl 	/* skip the delimiting spaces */
63*cb5caa98Sdjl 	while (linep < limit && isspace(*linep))
64*cb5caa98Sdjl 		linep++;
65*cb5caa98Sdjl 	/* skip port number */
66*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep) && *linep != '/')
67*cb5caa98Sdjl 		linep++;
68*cb5caa98Sdjl 	if (linep == limit || *linep != '/')
69*cb5caa98Sdjl 		return (0);
70*cb5caa98Sdjl 
71*cb5caa98Sdjl 	linep++;
72*cb5caa98Sdjl 	if ((keyp = argp->key.serv.proto) == NULL) {
73*cb5caa98Sdjl 		/* skip protocol */
74*cb5caa98Sdjl 		while (linep < limit && !isspace(*linep))
75*cb5caa98Sdjl 			linep++;
76*cb5caa98Sdjl 	} else {
77*cb5caa98Sdjl 		/* compare protocol */
78*cb5caa98Sdjl 		while (*keyp && linep < limit && !isspace(*linep) &&
79*cb5caa98Sdjl 				*keyp == *linep) {
80*cb5caa98Sdjl 			keyp++;
81*cb5caa98Sdjl 			linep++;
82*cb5caa98Sdjl 		}
83*cb5caa98Sdjl 		/* no protocol match */
84*cb5caa98Sdjl 		if (*keyp || (linep < limit && !isspace(*linep)))
85*cb5caa98Sdjl 			return (0);
86*cb5caa98Sdjl 		/* protocol and name match, return */
87*cb5caa98Sdjl 		if (name_match)
887c478bd9Sstevel@tonic-gate 			return (1);
89*cb5caa98Sdjl 		/* protocol match but name yet to be matched, so continue */
90*cb5caa98Sdjl 	}
91*cb5caa98Sdjl 
92*cb5caa98Sdjl 	/* compare with the aliases */
93*cb5caa98Sdjl 	while (linep < limit) {
94*cb5caa98Sdjl 		/* skip the delimiting spaces */
95*cb5caa98Sdjl 		while (linep < limit && isspace(*linep))
96*cb5caa98Sdjl 			linep++;
97*cb5caa98Sdjl 
98*cb5caa98Sdjl 		/* compare with the alias name */
99*cb5caa98Sdjl 		keyp = argp->key.serv.serv.name;
100*cb5caa98Sdjl 		while (*keyp && linep < limit && !isspace(*linep) &&
101*cb5caa98Sdjl 				*keyp == *linep) {
102*cb5caa98Sdjl 			keyp++;
103*cb5caa98Sdjl 			linep++;
1047c478bd9Sstevel@tonic-gate 		}
105*cb5caa98Sdjl 		if (*keyp == '\0' && (linep == limit || isspace(*linep)))
106*cb5caa98Sdjl 				return (1);
107*cb5caa98Sdjl 
108*cb5caa98Sdjl 		/* skip remainder of the alias name, if any */
109*cb5caa98Sdjl 		while (linep < limit && !isspace(*linep))
110*cb5caa98Sdjl 			linep++;
1117c478bd9Sstevel@tonic-gate 	}
1127c478bd9Sstevel@tonic-gate 	return (0);
1137c478bd9Sstevel@tonic-gate }
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate static nss_status_t
getbyname(be,a)1167c478bd9Sstevel@tonic-gate getbyname(be, a)
1177c478bd9Sstevel@tonic-gate 	files_backend_ptr_t	be;
1187c478bd9Sstevel@tonic-gate 	void			*a;
1197c478bd9Sstevel@tonic-gate {
120*cb5caa98Sdjl 	nss_XbyY_args_t		*argp = (nss_XbyY_args_t *)a;
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate 	return (_nss_files_XY_all(be, argp, 1,
1237c478bd9Sstevel@tonic-gate 				argp->key.serv.serv.name, check_name));
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate 
1267c478bd9Sstevel@tonic-gate static int
check_port(nss_XbyY_args_t * argp,const char * line,int linelen)127*cb5caa98Sdjl check_port(nss_XbyY_args_t *argp, const char *line, int linelen)
1287c478bd9Sstevel@tonic-gate {
129*cb5caa98Sdjl 	const char	*limit, *linep, *keyp, *numstart;
130*cb5caa98Sdjl 	int		numlen, s_port;
131*cb5caa98Sdjl 	char		numbuf[12], *numend;
132*cb5caa98Sdjl 
133*cb5caa98Sdjl 	linep = line;
134*cb5caa98Sdjl 	limit = line + linelen;
135*cb5caa98Sdjl 
136*cb5caa98Sdjl 	/* skip name */
137*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep))
138*cb5caa98Sdjl 		linep++;
139*cb5caa98Sdjl 	/* skip the delimiting spaces */
140*cb5caa98Sdjl 	while (linep < limit && isspace(*linep))
141*cb5caa98Sdjl 		linep++;
142*cb5caa98Sdjl 
143*cb5caa98Sdjl 	/* compare port num */
144*cb5caa98Sdjl 	numstart = linep;
145*cb5caa98Sdjl 	while (linep < limit && !isspace(*linep) && *linep != '/')
146*cb5caa98Sdjl 		linep++;
147*cb5caa98Sdjl 	if (linep == limit || *linep != '/')
148*cb5caa98Sdjl 		return (0);
149*cb5caa98Sdjl 	numlen = linep - numstart;
150*cb5caa98Sdjl 	if (numlen == 0 || numlen >= sizeof (numbuf))
151*cb5caa98Sdjl 		return (0);
152*cb5caa98Sdjl 	(void) memcpy(numbuf, numstart, numlen);
153*cb5caa98Sdjl 	numbuf[numlen] = '\0';
154*cb5caa98Sdjl 	s_port = htons((int)strtol(numbuf, &numend, 10));
155*cb5caa98Sdjl 	if (*numend != '\0')
156*cb5caa98Sdjl 		return (0);
157*cb5caa98Sdjl 	if (s_port == argp->key.serv.serv.port) {
158*cb5caa98Sdjl 		if ((keyp = argp->key.serv.proto) == NULL)
159*cb5caa98Sdjl 			return (1);
160*cb5caa98Sdjl 	} else
161*cb5caa98Sdjl 		return (0);
1627c478bd9Sstevel@tonic-gate 
163*cb5caa98Sdjl 	/* compare protocol */
164*cb5caa98Sdjl 	linep++;
165*cb5caa98Sdjl 	while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) {
166*cb5caa98Sdjl 		keyp++;
167*cb5caa98Sdjl 		linep++;
168*cb5caa98Sdjl 	}
169*cb5caa98Sdjl 	return (*keyp == '\0' && (linep == limit || isspace(*linep)));
1707c478bd9Sstevel@tonic-gate }
1717c478bd9Sstevel@tonic-gate 
1727c478bd9Sstevel@tonic-gate static nss_status_t
getbyport(be,a)1737c478bd9Sstevel@tonic-gate getbyport(be, a)
1747c478bd9Sstevel@tonic-gate 	files_backend_ptr_t	be;
1757c478bd9Sstevel@tonic-gate 	void			*a;
1767c478bd9Sstevel@tonic-gate {
177*cb5caa98Sdjl 	nss_XbyY_args_t		*argp	= (nss_XbyY_args_t *)a;
1787c478bd9Sstevel@tonic-gate 	char			portstr[12];
1797c478bd9Sstevel@tonic-gate 
180*cb5caa98Sdjl 	(void) snprintf(portstr, 12, "%d", ntohs(argp->key.serv.serv.port));
1817c478bd9Sstevel@tonic-gate 	return (_nss_files_XY_all(be, argp, 1, portstr, check_port));
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate static files_backend_op_t serv_ops[] = {
1857c478bd9Sstevel@tonic-gate 	_nss_files_destr,
1867c478bd9Sstevel@tonic-gate 	_nss_files_endent,
1877c478bd9Sstevel@tonic-gate 	_nss_files_setent,
1887c478bd9Sstevel@tonic-gate 	_nss_files_getent_netdb,
1897c478bd9Sstevel@tonic-gate 	getbyname,
1907c478bd9Sstevel@tonic-gate 	getbyport
1917c478bd9Sstevel@tonic-gate };
1927c478bd9Sstevel@tonic-gate 
1937c478bd9Sstevel@tonic-gate /*ARGSUSED*/
1947c478bd9Sstevel@tonic-gate nss_backend_t *
_nss_files_services_constr(dummy1,dummy2,dummy3)1957c478bd9Sstevel@tonic-gate _nss_files_services_constr(dummy1, dummy2, dummy3)
1967c478bd9Sstevel@tonic-gate 	const char	*dummy1, *dummy2, *dummy3;
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate 	return (_nss_files_constr(serv_ops,
1997c478bd9Sstevel@tonic-gate 				sizeof (serv_ops) / sizeof (serv_ops[0]),
2007c478bd9Sstevel@tonic-gate 				_PATH_SERVICES,
2017c478bd9Sstevel@tonic-gate 				NSS_LINELEN_SERVICES,
2027c478bd9Sstevel@tonic-gate 				NULL));
2037c478bd9Sstevel@tonic-gate }
204