1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * Portions of this source code were derived from Berkeley 4.3 BSD
32 * under license from the Regents of the University of California.
33 */
34
35 #pragma ident "%Z%%M% %I% %E% SMI"
36
37 #include <stdlib.h>
38 #include <dirent.h>
39 #include <string.h>
40 #include <malloc.h>
41 #include "ypsym.h"
42 #include "ypdefs.h"
43
44 /* Use N2L version of DBM calls */
45 #include "shim_hooks.h"
46
47 USE_YP_MASTER_NAME
48 USE_YP_LAST_MODIFIED
49 USE_YPDBPATH
50 USE_YP_SECURE
51 USE_DBM
52
53 #include <ctype.h>
54
55 static DBM *cur_fdb; /* will be passwd back up by ypset_current_map */
56 static enum { UNKNOWN, SECURE, PUBLIC } current_map_access = UNKNOWN;
57 static char map_owner[MAX_MASTER_NAME + 1];
58
59 extern unsigned int ypcheck_domain();
60 int check_secure_net_ti(struct netbuf *caller, char *ypname);
61
62 /*
63 * The retrieves the order number of a named map from the order number datum
64 * in the map data base.
65 */
66 bool
ypget_map_order(char * map,char * domain,uint_t * order)67 ypget_map_order(char *map, char *domain, uint_t *order)
68 {
69 datum key;
70 datum val;
71 char toconvert[MAX_ASCII_ORDER_NUMBER_LENGTH + 1];
72 uint_t error;
73 DBM *fdb;
74
75 if ((fdb = ypset_current_map(map, domain, &error)) != NULL) {
76 key.dptr = yp_last_modified;
77 key.dsize = yp_last_modified_sz;
78 val = dbm_fetch(fdb, key);
79
80 if (val.dptr != (char *)NULL) {
81
82 if (val.dsize > MAX_ASCII_ORDER_NUMBER_LENGTH) {
83 return (FALSE);
84 }
85
86 /*
87 * This is getting recopied here because val.dptr
88 * points to static memory owned by the dbm package,
89 * and we have no idea whether numeric characters
90 * follow the order number characters, nor whether
91 * the mess is null-terminated at all.
92 */
93
94 memcpy(toconvert, val.dptr, val.dsize);
95 toconvert[val.dsize] = '\0';
96 *order = (unsigned long) atol(toconvert);
97 return (TRUE);
98 } else {
99 return (FALSE);
100 }
101
102 } else {
103 return (FALSE);
104 }
105 }
106
107 /*
108 * The retrieves the master server name of a named map from the master datum
109 * in the map data base.
110 */
111 bool
ypget_map_master(char ** owner,DBM * fdb)112 ypget_map_master(char **owner, DBM *fdb)
113 {
114 datum key;
115 datum val;
116
117 key.dptr = yp_master_name;
118 key.dsize = yp_master_name_sz;
119 val = dbm_fetch(fdb, key);
120
121 if (val.dptr != (char *)NULL) {
122
123 if (val.dsize > MAX_MASTER_NAME) {
124 return (FALSE);
125 }
126
127 /*
128 * This is getting recopied here because val.dptr
129 * points to static memory owned by the dbm package.
130 */
131 memcpy(map_owner, val.dptr, val.dsize);
132 map_owner[val.dsize] = '\0';
133 *owner = map_owner;
134 return (TRUE);
135 } else {
136 return (FALSE);
137 }
138 }
139
140 /*
141 * This makes a map into the current map, and calls dbminit on that map
142 * and returns the DBM pointer to the map. Procedures called by
143 * ypserv dispatch routine would use this pointer for successive
144 * ndbm operations. Returns an YP_xxxx error code in error if FALSE.
145 */
146 DBM *
ypset_current_map(char * map,char * domain,uint_t * error)147 ypset_current_map(char *map, char *domain, uint_t *error)
148 {
149 char mapname[MAXNAMLEN + 1];
150 int lenm, lend;
151
152 /* Do not allow any path as a domain name or a map name. */
153 if (!map || ((lenm = (int)strlen(map)) == 0) || (lenm > YPMAXMAP) ||
154 !domain || ((lend = (int)strlen(domain)) == 0) ||
155 (lend > YPMAXDOMAIN) || (strchr(map, '/') != NULL) ||
156 (strchr(domain, '/') != NULL)) {
157 *error = YP_BADARGS;
158 return (FALSE);
159 }
160
161 if (FALSE == ypmkfilename(domain, map, mapname))
162 return (FALSE);
163
164 if ((cur_fdb) && (strcmp(mapname, get_map_name(cur_fdb)) == 0)) {
165 return (cur_fdb);
166 }
167
168 /* If there was a previous open map close it */
169 if (NULL != cur_fdb)
170 dbm_close(cur_fdb);
171
172 /* Set the map access as "unknown" as the new map has not been loaded */
173 current_map_access = UNKNOWN;
174
175 /* All the map locking is now handled inside the dbm_open shim */
176 if ((cur_fdb = dbm_open(mapname, O_RDWR, 0644)) != NULL) {
177 return (cur_fdb);
178 }
179
180 if (ypcheck_domain(domain)) {
181
182 if (ypcheck_map_existence(mapname)) {
183 *error = YP_BADDB;
184 } else {
185 *error = YP_NOMAP;
186 }
187
188 } else {
189 *error = YP_NODOM;
190 }
191
192 return (NULL);
193 }
194
195 /*
196 * This checks to see if there is a current map, and, if there is, does a
197 * dbmclose on it and sets the current map name and its DBM ptr to null.
198 */
199 void
ypclr_current_map(void)200 ypclr_current_map(void)
201 {
202 if (cur_fdb != NULL) {
203 (void) dbm_close(cur_fdb);
204 cur_fdb = NULL;
205 }
206 current_map_access = UNKNOWN;
207 }
208
209 /*
210 * Checks to see if caller has permission to query the current map (as
211 * set by ypset_current_map()). Returns TRUE if access is granted and
212 * FALSE otherwise. If FALSE then sets *error to YP_xxxxxxxx.
213 */
214 bool
yp_map_access(SVCXPRT * transp,uint_t * error,DBM * fdb)215 yp_map_access(SVCXPRT *transp, uint_t *error, DBM *fdb)
216 {
217 char *ypname = "ypserv";
218 struct netbuf *nbuf;
219 sa_family_t af;
220 in_port_t port;
221
222 nbuf = svc_getrpccaller(transp);
223 af = ((struct sockaddr_storage *)nbuf->buf)->ss_family;
224 if (af != AF_INET && af != AF_INET6)
225 return (FALSE);
226
227 if (!(check_secure_net_ti(nbuf, ypname))) {
228 *error = YP_NOMAP;
229 return (FALSE);
230 }
231
232 /* XXX - I expect that this won't happen much */
233 if (current_map_access == PUBLIC) {
234 return (TRUE);
235 }
236
237 if (af == AF_INET6) {
238 port = ntohs(((struct sockaddr_in6 *)nbuf->buf)->sin6_port);
239 } else {
240 port = ntohs(((struct sockaddr_in *)nbuf->buf)->sin_port);
241 }
242 if (port < IPPORT_RESERVED) {
243 return (TRUE);
244 }
245
246 if (current_map_access == UNKNOWN) {
247 datum key;
248 datum val;
249
250 key.dptr = yp_secure;
251 key.dsize = yp_secure_sz;
252 val = dbm_fetch(fdb, key);
253 if (val.dptr == (char *)NULL) {
254 current_map_access = PUBLIC;
255 return (TRUE);
256 }
257 current_map_access = SECURE;
258 }
259
260 /* current_map_access == SECURE and non-priviledged caller */
261 *error = YP_NOMAP;
262 return (FALSE);
263 }
264