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