1 /*
2    protocols.c - NSS lookup functions for protocol database
3 
4    Copyright (C) 2006 West Consulting
5    Copyright (C) 2006-2015 Arthur de Jong
6    Copyright (C) 2010 Symas Corporation
7 
8    This library is free software; you can redistribute it and/or
9    modify it under the terms of the GNU Lesser General Public
10    License as published by the Free Software Foundation; either
11    version 2.1 of the License, or (at your option) any later version.
12 
13    This library is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    Lesser General Public License for more details.
17 
18    You should have received a copy of the GNU Lesser General Public
19    License along with this library; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301 USA
22 */
23 
24 #include "config.h"
25 
26 #include <string.h>
27 #include <errno.h>
28 
29 #include "prototypes.h"
30 #include "common.h"
31 #include "compat/attrs.h"
32 
33 /* read a single protocol entry from the stream */
read_protoent(TFILE * fp,struct protoent * result,char * buffer,size_t buflen,int * errnop)34 static nss_status_t read_protoent(TFILE *fp, struct protoent *result,
35                                   char *buffer, size_t buflen, int *errnop)
36 {
37   int32_t tmpint32, tmp2int32, tmp3int32;
38   size_t bufptr = 0;
39   memset(result, 0, sizeof(struct protoent));
40   READ_BUF_STRING(fp, result->p_name);
41   READ_BUF_STRINGLIST(fp, result->p_aliases);
42   READ_INT32(fp, result->p_proto);
43   return NSS_STATUS_SUCCESS;
44 }
45 
46 #ifdef NSS_FLAVOUR_GLIBC
47 
48 /* get a protocol entry by name */
NSS_NAME(getprotobyname_r)49 nss_status_t NSS_NAME(getprotobyname_r)(const char *name,
50                                         struct protoent *result,
51                                         char *buffer, size_t buflen,
52                                         int *errnop)
53 {
54   NSS_GETONE(NSLCD_ACTION_PROTOCOL_BYNAME,
55              WRITE_STRING(fp, name),
56              read_protoent(fp, result, buffer, buflen, errnop));
57 }
58 
59 /* get a protocol entry by number */
NSS_NAME(getprotobynumber_r)60 nss_status_t NSS_NAME(getprotobynumber_r)(int number, struct protoent *result,
61                                           char *buffer, size_t buflen,
62                                           int *errnop)
63 {
64   NSS_GETONE(NSLCD_ACTION_PROTOCOL_BYNUMBER,
65              WRITE_INT32(fp, number),
66              read_protoent(fp, result, buffer, buflen, errnop));
67 }
68 
69 /* thread-local file pointer to an ongoing request */
70 static TLS TFILE *protoentfp;
71 
72 /* start a request to read all protocol entries */
NSS_NAME(setprotoent)73 nss_status_t NSS_NAME(setprotoent)(int UNUSED(stayopen))
74 {
75   NSS_SETENT(protoentfp);
76 }
77 
78 /* get a single protocol entry */
NSS_NAME(getprotoent_r)79 nss_status_t NSS_NAME(getprotoent_r)(struct protoent *result,
80                                      char *buffer, size_t buflen, int *errnop)
81 {
82   NSS_GETENT(protoentfp, NSLCD_ACTION_PROTOCOL_ALL,
83              read_protoent(protoentfp, result, buffer, buflen, errnop));
84 }
85 
86 /* close the stream opened by setprotoent() above */
NSS_NAME(endprotoent)87 nss_status_t NSS_NAME(endprotoent)(void)
88 {
89   NSS_ENDENT(protoentfp);
90 }
91 
92 #endif /* NSS_FLAVOUR_GLIBC */
93 
94 #ifdef NSS_FLAVOUR_SOLARIS
95 
96 #ifdef HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN
protoent2str(struct protoent * result,char * buffer,size_t buflen)97 static char *protoent2str(struct protoent *result, char *buffer, size_t buflen)
98 {
99   int res, i;
100   res = snprintf(buffer, buflen, "%s\t\t%d", result->p_name, result->p_proto);
101   if ((res < 0) || (res >= (int)buflen))
102     return NULL;
103   if (result->p_aliases)
104     for (i = 0; result->p_aliases[i]; i++)
105     {
106       strlcat(buffer, " ", buflen);
107       strlcat(buffer, result->p_aliases[i], buflen);
108     }
109   if (strlen(buffer) >= buflen - 1)
110     return NULL;
111   return buffer;
112 }
113 #endif /* HAVE_STRUCT_NSS_XBYY_ARGS_RETURNLEN */
114 
read_result(TFILE * fp,nss_XbyY_args_t * args)115 static nss_status_t read_result(TFILE *fp, nss_XbyY_args_t *args)
116 {
117   READ_RESULT(protoent, &args->erange);
118 }
119 
protocols_getprotobyname(nss_backend_t UNUSED (* be),void * args)120 static nss_status_t protocols_getprotobyname(nss_backend_t UNUSED(*be), void *args)
121 {
122   NSS_GETONE(NSLCD_ACTION_PROTOCOL_BYNAME,
123              WRITE_STRING(fp, NSS_ARGS(args)->key.name),
124              read_result(fp, args));
125 }
126 
protocols_getprotobynumber(nss_backend_t UNUSED (* be),void * args)127 static nss_status_t protocols_getprotobynumber(nss_backend_t UNUSED(*be), void *args)
128 {
129   NSS_GETONE(NSLCD_ACTION_PROTOCOL_BYNUMBER,
130              WRITE_INT32(fp, NSS_ARGS(args)->key.number),
131              read_result(fp, args));
132 }
133 
protocols_setprotoent(nss_backend_t * be,void UNUSED (* args))134 static nss_status_t protocols_setprotoent(nss_backend_t *be, void UNUSED(*args))
135 {
136   NSS_SETENT(LDAP_BE(be)->fp);
137 }
138 
protocols_getprotoent(nss_backend_t * be,void * args)139 static nss_status_t protocols_getprotoent(nss_backend_t *be, void *args)
140 {
141   NSS_GETENT(LDAP_BE(be)->fp, NSLCD_ACTION_PROTOCOL_ALL,
142              read_result(LDAP_BE(be)->fp, args));
143 }
144 
protocols_endprotoent(nss_backend_t * be,void UNUSED (* args))145 static nss_status_t protocols_endprotoent(nss_backend_t *be, void UNUSED(*args))
146 {
147   NSS_ENDENT(LDAP_BE(be)->fp);
148 }
149 
150 static nss_backend_op_t protocols_ops[] = {
151   nss_ldap_destructor,
152   protocols_endprotoent,
153   protocols_setprotoent,
154   protocols_getprotoent,
155   protocols_getprotobyname,
156   protocols_getprotobynumber
157 };
158 
NSS_NAME(protocols_constr)159 nss_backend_t *NSS_NAME(protocols_constr)(const char UNUSED(*db_name),
160                                           const char UNUSED(*src_name),
161                                           const char UNUSED(*cfg_args))
162 {
163   return nss_ldap_constructor(protocols_ops, sizeof(protocols_ops));
164 }
165 
166 #endif /* NSS_FLAVOUR_SOLARIS */
167