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