xref: /titanic_51/usr/src/cmd/fs.d/nfs/lib/ref_subr.c (revision 2f172c55ef76964744bc62b4500ece87f3089b4d)
1*2f172c55SRobert Thurlow /*
2*2f172c55SRobert Thurlow  * CDDL HEADER START
3*2f172c55SRobert Thurlow  *
4*2f172c55SRobert Thurlow  * The contents of this file are subject to the terms of the
5*2f172c55SRobert Thurlow  * Common Development and Distribution License (the "License").
6*2f172c55SRobert Thurlow  * You may not use this file except in compliance with the License.
7*2f172c55SRobert Thurlow  *
8*2f172c55SRobert Thurlow  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*2f172c55SRobert Thurlow  * or http://www.opensolaris.org/os/licensing.
10*2f172c55SRobert Thurlow  * See the License for the specific language governing permissions
11*2f172c55SRobert Thurlow  * and limitations under the License.
12*2f172c55SRobert Thurlow  *
13*2f172c55SRobert Thurlow  * When distributing Covered Code, include this CDDL HEADER in each
14*2f172c55SRobert Thurlow  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*2f172c55SRobert Thurlow  * If applicable, add the following below this CDDL HEADER, with the
16*2f172c55SRobert Thurlow  * fields enclosed by brackets "[]" replaced with your own identifying
17*2f172c55SRobert Thurlow  * information: Portions Copyright [yyyy] [name of copyright owner]
18*2f172c55SRobert Thurlow  *
19*2f172c55SRobert Thurlow  * CDDL HEADER END
20*2f172c55SRobert Thurlow  */
21*2f172c55SRobert Thurlow 
22*2f172c55SRobert Thurlow /*
23*2f172c55SRobert Thurlow  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24*2f172c55SRobert Thurlow  * Use is subject to license terms.
25*2f172c55SRobert Thurlow  */
26*2f172c55SRobert Thurlow 
27*2f172c55SRobert Thurlow #include <stdio.h>
28*2f172c55SRobert Thurlow #include <unistd.h>
29*2f172c55SRobert Thurlow #include <strings.h>
30*2f172c55SRobert Thurlow #include <string.h>
31*2f172c55SRobert Thurlow #include <sys/types.h>
32*2f172c55SRobert Thurlow #include <sys/stat.h>
33*2f172c55SRobert Thurlow #include <sys/errno.h>
34*2f172c55SRobert Thurlow #include <limits.h>
35*2f172c55SRobert Thurlow #include <libnvpair.h>
36*2f172c55SRobert Thurlow #include <dlfcn.h>
37*2f172c55SRobert Thurlow #include <link.h>
38*2f172c55SRobert Thurlow #include <rp_plugin.h>
39*2f172c55SRobert Thurlow #include <fcntl.h>
40*2f172c55SRobert Thurlow #include <uuid/uuid.h>
41*2f172c55SRobert Thurlow #include <rpc/types.h>
42*2f172c55SRobert Thurlow #include <rpc/xdr.h>
43*2f172c55SRobert Thurlow #include <rpc/auth.h>
44*2f172c55SRobert Thurlow #include <rpc/clnt.h>
45*2f172c55SRobert Thurlow #include <rpc/rpc_msg.h>
46*2f172c55SRobert Thurlow #include <sys/param.h>
47*2f172c55SRobert Thurlow #include <nfs/nfs4.h>
48*2f172c55SRobert Thurlow #include <rpcsvc/nfs4_prot.h>
49*2f172c55SRobert Thurlow 
50*2f172c55SRobert Thurlow /*
51*2f172c55SRobert Thurlow  * str_to_utf8 - converts a null-terminated C string to a utf8 string
52*2f172c55SRobert Thurlow  */
53*2f172c55SRobert Thurlow utf8string *
54*2f172c55SRobert Thurlow str_to_utf8(char *nm, utf8string *str)
55*2f172c55SRobert Thurlow {
56*2f172c55SRobert Thurlow 	int len;
57*2f172c55SRobert Thurlow 
58*2f172c55SRobert Thurlow 	if (str == NULL)
59*2f172c55SRobert Thurlow 		return (NULL);
60*2f172c55SRobert Thurlow 
61*2f172c55SRobert Thurlow 	if (nm == NULL || *nm == '\0') {
62*2f172c55SRobert Thurlow 		str->utf8string_len = 0;
63*2f172c55SRobert Thurlow 		str->utf8string_val = NULL;
64*2f172c55SRobert Thurlow 		return (NULL);
65*2f172c55SRobert Thurlow 	}
66*2f172c55SRobert Thurlow 
67*2f172c55SRobert Thurlow 	len = strlen(nm);
68*2f172c55SRobert Thurlow 
69*2f172c55SRobert Thurlow 	str->utf8string_val = malloc(len);
70*2f172c55SRobert Thurlow 	if (str->utf8string_val == NULL) {
71*2f172c55SRobert Thurlow 		str->utf8string_len = 0;
72*2f172c55SRobert Thurlow 		return (NULL);
73*2f172c55SRobert Thurlow 	}
74*2f172c55SRobert Thurlow 	str->utf8string_len = len;
75*2f172c55SRobert Thurlow 	bcopy(nm, str->utf8string_val, len);
76*2f172c55SRobert Thurlow 
77*2f172c55SRobert Thurlow 	return (str);
78*2f172c55SRobert Thurlow }
79*2f172c55SRobert Thurlow 
80*2f172c55SRobert Thurlow /*
81*2f172c55SRobert Thurlow  * Converts a utf8 string to a C string.
82*2f172c55SRobert Thurlow  * kmem_allocs a new string if not supplied
83*2f172c55SRobert Thurlow  */
84*2f172c55SRobert Thurlow char *
85*2f172c55SRobert Thurlow utf8_to_str(utf8string *str, uint_t *lenp, char *s)
86*2f172c55SRobert Thurlow {
87*2f172c55SRobert Thurlow 	char	*sp;
88*2f172c55SRobert Thurlow 	char	*u8p;
89*2f172c55SRobert Thurlow 	int	len;
90*2f172c55SRobert Thurlow 	int	 i;
91*2f172c55SRobert Thurlow 
92*2f172c55SRobert Thurlow 	if (str == NULL)
93*2f172c55SRobert Thurlow 		return (NULL);
94*2f172c55SRobert Thurlow 
95*2f172c55SRobert Thurlow 	u8p = str->utf8string_val;
96*2f172c55SRobert Thurlow 	len = str->utf8string_len;
97*2f172c55SRobert Thurlow 	if (len <= 0 || u8p == NULL) {
98*2f172c55SRobert Thurlow 		if (s)
99*2f172c55SRobert Thurlow 			*s = '\0';
100*2f172c55SRobert Thurlow 		return (NULL);
101*2f172c55SRobert Thurlow 	}
102*2f172c55SRobert Thurlow 
103*2f172c55SRobert Thurlow 	sp = s;
104*2f172c55SRobert Thurlow 	if (sp == NULL)
105*2f172c55SRobert Thurlow 		sp = malloc(len + 1);
106*2f172c55SRobert Thurlow 	if (sp == NULL)
107*2f172c55SRobert Thurlow 		return (NULL);
108*2f172c55SRobert Thurlow 
109*2f172c55SRobert Thurlow 	/*
110*2f172c55SRobert Thurlow 	 * At least check for embedded nulls
111*2f172c55SRobert Thurlow 	 */
112*2f172c55SRobert Thurlow 	for (i = 0; i < len; i++) {
113*2f172c55SRobert Thurlow 		sp[i] = u8p[i];
114*2f172c55SRobert Thurlow 		if (u8p[i] == '\0') {
115*2f172c55SRobert Thurlow 			if (s == NULL)
116*2f172c55SRobert Thurlow 				free(sp);
117*2f172c55SRobert Thurlow 			return (NULL);
118*2f172c55SRobert Thurlow 		}
119*2f172c55SRobert Thurlow 	}
120*2f172c55SRobert Thurlow 	sp[len] = '\0';
121*2f172c55SRobert Thurlow 	*lenp = len + 1;
122*2f172c55SRobert Thurlow 
123*2f172c55SRobert Thurlow 	return (sp);
124*2f172c55SRobert Thurlow }
125*2f172c55SRobert Thurlow 
126*2f172c55SRobert Thurlow void
127*2f172c55SRobert Thurlow print_referral_summary(fs_locations4 *fsl)
128*2f172c55SRobert Thurlow {
129*2f172c55SRobert Thurlow 	int i, j;
130*2f172c55SRobert Thurlow 	uint_t l;
131*2f172c55SRobert Thurlow 	char *s;
132*2f172c55SRobert Thurlow 	fs_location4 *fs;
133*2f172c55SRobert Thurlow 
134*2f172c55SRobert Thurlow 	if (fsl == NULL) {
135*2f172c55SRobert Thurlow 		printf("NULL\n");
136*2f172c55SRobert Thurlow 		return;
137*2f172c55SRobert Thurlow 	}
138*2f172c55SRobert Thurlow 
139*2f172c55SRobert Thurlow 	for (i = 0; i < fsl->locations.locations_len; i++) {
140*2f172c55SRobert Thurlow 		if (i > 0)
141*2f172c55SRobert Thurlow 			printf("\n");
142*2f172c55SRobert Thurlow 		fs = &fsl->locations.locations_val[i];
143*2f172c55SRobert Thurlow 		for (j = 0; j < fs->server.server_len; j++) {
144*2f172c55SRobert Thurlow 			s = utf8_to_str(&fs->server.server_val[j], &l, NULL);
145*2f172c55SRobert Thurlow 			if (j > 0)
146*2f172c55SRobert Thurlow 				printf(",");
147*2f172c55SRobert Thurlow 			printf("%s", s ? s : "");
148*2f172c55SRobert Thurlow 			if (s)
149*2f172c55SRobert Thurlow 				free(s);
150*2f172c55SRobert Thurlow 		}
151*2f172c55SRobert Thurlow 		printf(":");
152*2f172c55SRobert Thurlow 		for (j = 0; j < fs->rootpath.pathname4_len; j++) {
153*2f172c55SRobert Thurlow 			s = utf8_to_str(&fs->rootpath.pathname4_val[j],
154*2f172c55SRobert Thurlow 			    &l, NULL);
155*2f172c55SRobert Thurlow 			printf("/%s", s ? s : "");
156*2f172c55SRobert Thurlow 			if (s)
157*2f172c55SRobert Thurlow 				free(s);
158*2f172c55SRobert Thurlow 		}
159*2f172c55SRobert Thurlow 		if (fs->rootpath.pathname4_len == 0)
160*2f172c55SRobert Thurlow 			printf("/");
161*2f172c55SRobert Thurlow 	}
162*2f172c55SRobert Thurlow 	printf("\n");
163*2f172c55SRobert Thurlow }
164*2f172c55SRobert Thurlow 
165*2f172c55SRobert Thurlow /*
166*2f172c55SRobert Thurlow  * There is a kernel copy of this routine in nfs4_srv.c.
167*2f172c55SRobert Thurlow  * Changes should be kept in sync.
168*2f172c55SRobert Thurlow  */
169*2f172c55SRobert Thurlow static int
170*2f172c55SRobert Thurlow nfs4_create_components(char *path, component4 *comp4)
171*2f172c55SRobert Thurlow {
172*2f172c55SRobert Thurlow 	int slen, plen, ncomp;
173*2f172c55SRobert Thurlow 	char *ori_path, *nxtc, buf[MAXNAMELEN];
174*2f172c55SRobert Thurlow 
175*2f172c55SRobert Thurlow 	if (path == NULL)
176*2f172c55SRobert Thurlow 		return (0);
177*2f172c55SRobert Thurlow 
178*2f172c55SRobert Thurlow 	plen = strlen(path) + 1;	/* include the terminator */
179*2f172c55SRobert Thurlow 	ori_path = path;
180*2f172c55SRobert Thurlow 	ncomp = 0;
181*2f172c55SRobert Thurlow 
182*2f172c55SRobert Thurlow 	/* count number of components in the path */
183*2f172c55SRobert Thurlow 	for (nxtc = path; nxtc < ori_path + plen; nxtc++) {
184*2f172c55SRobert Thurlow 		if (*nxtc == '/' || *nxtc == '\0' || *nxtc == '\n') {
185*2f172c55SRobert Thurlow 			if ((slen = nxtc - path) == 0) {
186*2f172c55SRobert Thurlow 				path = nxtc + 1;
187*2f172c55SRobert Thurlow 				continue;
188*2f172c55SRobert Thurlow 			}
189*2f172c55SRobert Thurlow 
190*2f172c55SRobert Thurlow 			if (comp4 != NULL) {
191*2f172c55SRobert Thurlow 				bcopy(path, buf, slen);
192*2f172c55SRobert Thurlow 				buf[slen] = '\0';
193*2f172c55SRobert Thurlow 				if (str_to_utf8(buf, &comp4[ncomp]) == NULL)
194*2f172c55SRobert Thurlow 					return (NULL);
195*2f172c55SRobert Thurlow 			}
196*2f172c55SRobert Thurlow 
197*2f172c55SRobert Thurlow 			ncomp++;	/* 1 valid component */
198*2f172c55SRobert Thurlow 			path = nxtc + 1;
199*2f172c55SRobert Thurlow 		}
200*2f172c55SRobert Thurlow 		if (*nxtc == '\0' || *nxtc == '\n')
201*2f172c55SRobert Thurlow 			break;
202*2f172c55SRobert Thurlow 	}
203*2f172c55SRobert Thurlow 
204*2f172c55SRobert Thurlow 	return (ncomp);
205*2f172c55SRobert Thurlow }
206*2f172c55SRobert Thurlow 
207*2f172c55SRobert Thurlow /*
208*2f172c55SRobert Thurlow  * There is a kernel copy of this routine in nfs4_srv.c.
209*2f172c55SRobert Thurlow  * Changes should be kept in sync.
210*2f172c55SRobert Thurlow  */
211*2f172c55SRobert Thurlow int
212*2f172c55SRobert Thurlow make_pathname4(char *path, pathname4 *pathname)
213*2f172c55SRobert Thurlow {
214*2f172c55SRobert Thurlow 	int ncomp;
215*2f172c55SRobert Thurlow 	component4 *comp4;
216*2f172c55SRobert Thurlow 
217*2f172c55SRobert Thurlow 	if (pathname == NULL)
218*2f172c55SRobert Thurlow 		return (0);
219*2f172c55SRobert Thurlow 
220*2f172c55SRobert Thurlow 	if (path == NULL) {
221*2f172c55SRobert Thurlow 		pathname->pathname4_val = NULL;
222*2f172c55SRobert Thurlow 		pathname->pathname4_len = 0;
223*2f172c55SRobert Thurlow 		return (0);
224*2f172c55SRobert Thurlow 	}
225*2f172c55SRobert Thurlow 
226*2f172c55SRobert Thurlow 	/* count number of components to alloc buffer */
227*2f172c55SRobert Thurlow 	if ((ncomp = nfs4_create_components(path, NULL)) == 0) {
228*2f172c55SRobert Thurlow 		pathname->pathname4_val = NULL;
229*2f172c55SRobert Thurlow 		pathname->pathname4_len = 0;
230*2f172c55SRobert Thurlow 		return (0);
231*2f172c55SRobert Thurlow 	}
232*2f172c55SRobert Thurlow 	comp4 = calloc(ncomp * sizeof (component4), 1);
233*2f172c55SRobert Thurlow 	if (comp4 == NULL) {
234*2f172c55SRobert Thurlow 		pathname->pathname4_val = NULL;
235*2f172c55SRobert Thurlow 		pathname->pathname4_len = 0;
236*2f172c55SRobert Thurlow 		return (0);
237*2f172c55SRobert Thurlow 	}
238*2f172c55SRobert Thurlow 
239*2f172c55SRobert Thurlow 	/* copy components into allocated buffer */
240*2f172c55SRobert Thurlow 	ncomp = nfs4_create_components(path, comp4);
241*2f172c55SRobert Thurlow 
242*2f172c55SRobert Thurlow 	pathname->pathname4_val = comp4;
243*2f172c55SRobert Thurlow 	pathname->pathname4_len = ncomp;
244*2f172c55SRobert Thurlow 
245*2f172c55SRobert Thurlow 	return (ncomp);
246*2f172c55SRobert Thurlow }
247*2f172c55SRobert Thurlow 
248*2f172c55SRobert Thurlow bool_t
249*2f172c55SRobert Thurlow xdr_component4(register XDR *xdrs, component4 *objp)
250*2f172c55SRobert Thurlow {
251*2f172c55SRobert Thurlow 
252*2f172c55SRobert Thurlow 	if (!xdr_utf8string(xdrs, objp))
253*2f172c55SRobert Thurlow 		return (FALSE);
254*2f172c55SRobert Thurlow 	return (TRUE);
255*2f172c55SRobert Thurlow }
256*2f172c55SRobert Thurlow 
257*2f172c55SRobert Thurlow bool_t
258*2f172c55SRobert Thurlow xdr_utf8string(register XDR *xdrs, utf8string *objp)
259*2f172c55SRobert Thurlow {
260*2f172c55SRobert Thurlow 
261*2f172c55SRobert Thurlow 	if (xdrs->x_op != XDR_FREE)
262*2f172c55SRobert Thurlow 		return (xdr_bytes(xdrs, (char **)&objp->utf8string_val,
263*2f172c55SRobert Thurlow 		    (uint_t *)&objp->utf8string_len, NFS4_MAX_UTF8STRING));
264*2f172c55SRobert Thurlow 	return (TRUE);
265*2f172c55SRobert Thurlow }
266*2f172c55SRobert Thurlow 
267*2f172c55SRobert Thurlow bool_t
268*2f172c55SRobert Thurlow xdr_pathname4(register XDR *xdrs, pathname4 *objp)
269*2f172c55SRobert Thurlow {
270*2f172c55SRobert Thurlow 
271*2f172c55SRobert Thurlow 	if (!xdr_array(xdrs, (char **)&objp->pathname4_val,
272*2f172c55SRobert Thurlow 	    (uint_t *)&objp->pathname4_len, NFS4_MAX_PATHNAME4,
273*2f172c55SRobert Thurlow 	    sizeof (component4), (xdrproc_t)xdr_component4))
274*2f172c55SRobert Thurlow 		return (FALSE);
275*2f172c55SRobert Thurlow 	return (TRUE);
276*2f172c55SRobert Thurlow }
277*2f172c55SRobert Thurlow 
278*2f172c55SRobert Thurlow bool_t
279*2f172c55SRobert Thurlow xdr_fs_location4(register XDR *xdrs, fs_location4 *objp)
280*2f172c55SRobert Thurlow {
281*2f172c55SRobert Thurlow 
282*2f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
283*2f172c55SRobert Thurlow 		objp->server.server_val = NULL;
284*2f172c55SRobert Thurlow 		objp->rootpath.pathname4_val = NULL;
285*2f172c55SRobert Thurlow 	}
286*2f172c55SRobert Thurlow 	if (!xdr_array(xdrs, (char **)&objp->server.server_val,
287*2f172c55SRobert Thurlow 	    (uint_t *)&objp->server.server_len, ~0,
288*2f172c55SRobert Thurlow 	    sizeof (utf8string), (xdrproc_t)xdr_utf8string))
289*2f172c55SRobert Thurlow 		return (FALSE);
290*2f172c55SRobert Thurlow 	if (!xdr_pathname4(xdrs, &objp->rootpath))
291*2f172c55SRobert Thurlow 		return (FALSE);
292*2f172c55SRobert Thurlow 	return (TRUE);
293*2f172c55SRobert Thurlow }
294*2f172c55SRobert Thurlow 
295*2f172c55SRobert Thurlow bool_t
296*2f172c55SRobert Thurlow xdr_fs_locations4(register XDR *xdrs, fs_locations4 *objp)
297*2f172c55SRobert Thurlow {
298*2f172c55SRobert Thurlow 
299*2f172c55SRobert Thurlow 	if (xdrs->x_op == XDR_DECODE) {
300*2f172c55SRobert Thurlow 		objp->fs_root.pathname4_len = 0;
301*2f172c55SRobert Thurlow 		objp->fs_root.pathname4_val = NULL;
302*2f172c55SRobert Thurlow 		objp->locations.locations_val = NULL;
303*2f172c55SRobert Thurlow 	}
304*2f172c55SRobert Thurlow 	if (!xdr_pathname4(xdrs, &objp->fs_root))
305*2f172c55SRobert Thurlow 		return (FALSE);
306*2f172c55SRobert Thurlow 	if (!xdr_array(xdrs, (char **)&objp->locations.locations_val,
307*2f172c55SRobert Thurlow 	    (uint_t *)&objp->locations.locations_len, ~0,
308*2f172c55SRobert Thurlow 	    sizeof (fs_location4), (xdrproc_t)xdr_fs_location4))
309*2f172c55SRobert Thurlow 		return (FALSE);
310*2f172c55SRobert Thurlow 	return (TRUE);
311*2f172c55SRobert Thurlow }
312