xref: /illumos-gate/usr/src/cmd/ypcmd/ypserv_map.c (revision 2a8bcb4e)
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 #include <stdlib.h>
36 #include <dirent.h>
37 #include <string.h>
38 #include <malloc.h>
39 #include "ypsym.h"
40 #include "ypdefs.h"
41 
42 /* Use N2L version of DBM calls */
43 #include "shim_hooks.h"
44 
45 USE_YP_MASTER_NAME
46 USE_YP_LAST_MODIFIED
47 USE_YPDBPATH
48 USE_YP_SECURE
49 USE_DBM
50 
51 #include <ctype.h>
52 
53 static DBM *cur_fdb; /* will be passwd back up by ypset_current_map */
54 static enum { UNKNOWN, SECURE, PUBLIC } current_map_access = UNKNOWN;
55 static char map_owner[MAX_MASTER_NAME + 1];
56 
57 extern unsigned int ypcheck_domain();
58 int check_secure_net_ti(struct netbuf *caller, char *ypname);
59 
60 /*
61  * The retrieves the order number of a named map from the order number datum
62  * in the map data base.
63  */
64 bool
ypget_map_order(char * map,char * domain,uint_t * order)65 ypget_map_order(char *map, char *domain, uint_t *order)
66 {
67 	datum key;
68 	datum val;
69 	char toconvert[MAX_ASCII_ORDER_NUMBER_LENGTH + 1];
70 	uint_t error;
71 	DBM *fdb;
72 
73 	if ((fdb = ypset_current_map(map, domain, &error)) != NULL) {
74 		key.dptr = yp_last_modified;
75 		key.dsize = yp_last_modified_sz;
76 		val = dbm_fetch(fdb, key);
77 
78 		if (val.dptr != (char *)NULL) {
79 
80 			if (val.dsize > MAX_ASCII_ORDER_NUMBER_LENGTH) {
81 			return (FALSE);
82 			}
83 
84 			/*
85 			 * This is getting recopied here because val.dptr
86 			 * points to static memory owned by the dbm package,
87 			 * and we have no idea whether numeric characters
88 			 * follow the order number characters, nor whether
89 			 * the mess is null-terminated at all.
90 			 */
91 
92 			memcpy(toconvert, val.dptr, val.dsize);
93 			toconvert[val.dsize] = '\0';
94 			*order = (unsigned long) atol(toconvert);
95 			return (TRUE);
96 		} else {
97 			return (FALSE);
98 		}
99 
100 	} else {
101 		return (FALSE);
102 	}
103 }
104 
105 /*
106  * The retrieves the master server name of a named map from the master datum
107  * in the map data base.
108  */
109 bool
ypget_map_master(char ** owner,DBM * fdb)110 ypget_map_master(char **owner, DBM *fdb)
111 {
112 	datum key;
113 	datum val;
114 
115 	key.dptr = yp_master_name;
116 	key.dsize = yp_master_name_sz;
117 	val = dbm_fetch(fdb, key);
118 
119 	if (val.dptr != (char *)NULL) {
120 
121 		if (val.dsize > MAX_MASTER_NAME) {
122 			return (FALSE);
123 		}
124 
125 		/*
126 		 * This is getting recopied here because val.dptr
127 		 * points to static memory owned by the dbm package.
128 		 */
129 		memcpy(map_owner, val.dptr, val.dsize);
130 		map_owner[val.dsize] = '\0';
131 		*owner = map_owner;
132 		return (TRUE);
133 	} else {
134 		return (FALSE);
135 	}
136 }
137 
138 /*
139  * This makes a map into the current map, and calls dbminit on that map
140  * and returns the DBM pointer to the map. Procedures called by
141  * ypserv dispatch routine would use this pointer for successive
142  * ndbm operations.  Returns an YP_xxxx error code in error if FALSE.
143  */
144 DBM *
ypset_current_map(char * map,char * domain,uint_t * error)145 ypset_current_map(char *map, char *domain, uint_t *error)
146 {
147 	char mapname[MAXNAMLEN + 1];
148 	int lenm, lend;
149 
150 	/* Do not allow any path as a domain name or a map name.   */
151 	if (!map || ((lenm = (int)strlen(map)) == 0) || (lenm > YPMAXMAP) ||
152 	    !domain || ((lend = (int)strlen(domain)) == 0) ||
153 	    (lend > YPMAXDOMAIN) || (strchr(map, '/') != NULL) ||
154 	    (strchr(domain, '/') != NULL)) {
155 		*error = YP_BADARGS;
156 		return (FALSE);
157 	}
158 
159 	if (FALSE == ypmkfilename(domain, map, mapname))
160 		return (FALSE);
161 
162 	if ((cur_fdb) && (strcmp(mapname, get_map_name(cur_fdb)) == 0)) {
163 		return (cur_fdb);
164 	}
165 
166 	/* If there was a previous open map close it */
167 	if (NULL != cur_fdb)
168 		dbm_close(cur_fdb);
169 
170 	/* Set the map access as "unknown" as the new map has not been loaded */
171 	current_map_access = UNKNOWN;
172 
173 	/* All the map locking is now handled inside the dbm_open shim */
174 	if ((cur_fdb = dbm_open(mapname, O_RDWR, 0644)) != NULL) {
175 		return (cur_fdb);
176 	}
177 
178 	if (ypcheck_domain(domain)) {
179 
180 		if (ypcheck_map_existence(mapname)) {
181 			*error = YP_BADDB;
182 		} else {
183 			*error = YP_NOMAP;
184 		}
185 
186 	} else {
187 		*error = YP_NODOM;
188 	}
189 
190 	return (NULL);
191 }
192 
193 /*
194  * This checks to see if there is a current map, and, if there is, does a
195  * dbmclose on it and sets the current map name and its DBM ptr to null.
196  */
197 void
ypclr_current_map(void)198 ypclr_current_map(void)
199 {
200 	if (cur_fdb != NULL) {
201 		(void) dbm_close(cur_fdb);
202 		cur_fdb = NULL;
203 	}
204 	current_map_access = UNKNOWN;
205 }
206 
207 /*
208  * Checks to see if caller has permission to query the current map (as
209  * set by ypset_current_map()).  Returns TRUE if access is granted and
210  * FALSE otherwise.  If FALSE then sets *error to YP_xxxxxxxx.
211  */
212 bool
yp_map_access(SVCXPRT * transp,uint_t * error,DBM * fdb)213 yp_map_access(SVCXPRT *transp, uint_t *error, DBM *fdb)
214 {
215 	char *ypname = "ypserv";
216 	struct netbuf *nbuf;
217 	sa_family_t af;
218 	in_port_t port;
219 
220 	nbuf = svc_getrpccaller(transp);
221 	af = ((struct sockaddr_storage *)nbuf->buf)->ss_family;
222 	if (af != AF_INET && af != AF_INET6)
223 		return (FALSE);
224 
225 	if (!(check_secure_net_ti(nbuf, ypname))) {
226 		*error = YP_NOMAP;
227 		return (FALSE);
228 	}
229 
230 	/* XXX - I expect that this won't happen much */
231 	if (current_map_access == PUBLIC) {
232 		return (TRUE);
233 	}
234 
235 	if (af == AF_INET6) {
236 		port = ntohs(((struct sockaddr_in6 *)nbuf->buf)->sin6_port);
237 	} else {
238 		port = ntohs(((struct sockaddr_in *)nbuf->buf)->sin_port);
239 	}
240 	if (port < IPPORT_RESERVED) {
241 		return (TRUE);
242 	}
243 
244 	if (current_map_access == UNKNOWN) {
245 		datum key;
246 		datum val;
247 
248 		key.dptr = yp_secure;
249 		key.dsize = yp_secure_sz;
250 		val = dbm_fetch(fdb, key);
251 		if (val.dptr == (char *)NULL) {
252 			current_map_access = PUBLIC;
253 			return (TRUE);
254 		}
255 		current_map_access = SECURE;
256 	}
257 
258 	/* current_map_access == SECURE and non-priviledged caller */
259 	*error = YP_NOMAP;
260 	return (FALSE);
261 }
262