1*85e6b674SGordon Ross /*
2*85e6b674SGordon Ross * CDDL HEADER START
3*85e6b674SGordon Ross *
4*85e6b674SGordon Ross * The contents of this file are subject to the terms of the
5*85e6b674SGordon Ross * Common Development and Distribution License (the "License").
6*85e6b674SGordon Ross * You may not use this file except in compliance with the License.
7*85e6b674SGordon Ross *
8*85e6b674SGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*85e6b674SGordon Ross * or http://www.opensolaris.org/os/licensing.
10*85e6b674SGordon Ross * See the License for the specific language governing permissions
11*85e6b674SGordon Ross * and limitations under the License.
12*85e6b674SGordon Ross *
13*85e6b674SGordon Ross * When distributing Covered Code, include this CDDL HEADER in each
14*85e6b674SGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*85e6b674SGordon Ross * If applicable, add the following below this CDDL HEADER, with the
16*85e6b674SGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying
17*85e6b674SGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner]
18*85e6b674SGordon Ross *
19*85e6b674SGordon Ross * CDDL HEADER END
20*85e6b674SGordon Ross */
21*85e6b674SGordon Ross
22*85e6b674SGordon Ross /*
23*85e6b674SGordon Ross * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
24*85e6b674SGordon Ross * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
25*85e6b674SGordon Ross */
26*85e6b674SGordon Ross
27*85e6b674SGordon Ross /*
28*85e6b674SGordon Ross * Test program for the smbfs named pipe API.
29*85e6b674SGordon Ross */
30*85e6b674SGordon Ross
31*85e6b674SGordon Ross #include <sys/types.h>
32*85e6b674SGordon Ross #include <errno.h>
33*85e6b674SGordon Ross #include <fcntl.h>
34*85e6b674SGordon Ross #include <stdio.h>
35*85e6b674SGordon Ross #include <stdlib.h>
36*85e6b674SGordon Ross #include <string.h>
37*85e6b674SGordon Ross #include <unistd.h>
38*85e6b674SGordon Ross #include <libintl.h>
39*85e6b674SGordon Ross
40*85e6b674SGordon Ross #include <netsmb/smbfs_api.h>
41*85e6b674SGordon Ross
42*85e6b674SGordon Ross /*
43*85e6b674SGordon Ross * This is a quick hack for testing client-side named pipes.
44*85e6b674SGordon Ross * Its purpose is to test the ability to connect to a server,
45*85e6b674SGordon Ross * open a pipe, send and receive data. The "hack" aspect is
46*85e6b674SGordon Ross * the use of hand-crafted RPC messages, which allows testing
47*85e6b674SGordon Ross * of the named pipe API separately from the RPC libraries.
48*85e6b674SGordon Ross *
49*85e6b674SGordon Ross * I captured the two small name pipe messages sent when
50*85e6b674SGordon Ross * requesting a share list via RPC over /pipe/srvsvc and
51*85e6b674SGordon Ross * dropped them into the arrays below (bind and enum).
52*85e6b674SGordon Ross * This program sends the two messages (with adjustments)
53*85e6b674SGordon Ross * and just dumps whatever comes back over the pipe.
54*85e6b674SGordon Ross * Use wireshark if you want to see decoded messages.
55*85e6b674SGordon Ross */
56*85e6b674SGordon Ross
57*85e6b674SGordon Ross extern char *optarg;
58*85e6b674SGordon Ross extern int optind, opterr, optopt;
59*85e6b674SGordon Ross
60*85e6b674SGordon Ross /* This is a DCE/RPC bind call for "srvsvc". */
61*85e6b674SGordon Ross static const uchar_t
62*85e6b674SGordon Ross srvsvc_bind[] = {
63*85e6b674SGordon Ross 0x05, 0x00, 0x0b, 0x03, 0x10, 0x00, 0x00, 0x00,
64*85e6b674SGordon Ross 0x48, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
65*85e6b674SGordon Ross 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
66*85e6b674SGordon Ross 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00,
67*85e6b674SGordon Ross 0xc8, 0x4f, 0x32, 0x4b, 0x70, 0x16, 0xd3, 0x01,
68*85e6b674SGordon Ross 0x12, 0x78, 0x5a, 0x47, 0xbf, 0x6e, 0xe1, 0x88,
69*85e6b674SGordon Ross 0x03, 0x00, 0x00, 0x00, 0x04, 0x5d, 0x88, 0x8a,
70*85e6b674SGordon Ross 0xeb, 0x1c, 0xc9, 0x11, 0x9f, 0xe8, 0x08, 0x00,
71*85e6b674SGordon Ross 0x2b, 0x10, 0x48, 0x60, 0x02, 0x00, 0x00, 0x00 };
72*85e6b674SGordon Ross
73*85e6b674SGordon Ross /* This is a srvsvc "enum servers" call, in two parts */
74*85e6b674SGordon Ross static const uchar_t
75*85e6b674SGordon Ross srvsvc_enum1[] = {
76*85e6b674SGordon Ross 0x05, 0x00, 0x00, 0x03, 0x10, 0x00, 0x00, 0x00,
77*85e6b674SGordon Ross #define ENUM_RPCLEN_OFF 8
78*85e6b674SGordon Ross /* V - RPC frag length */
79*85e6b674SGordon Ross 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80*85e6b674SGordon Ross /* ... and the operation number is: VVVV */
81*85e6b674SGordon Ross 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0f, 0x00,
82*85e6b674SGordon Ross #define ENUM_SLEN1_OFF 28
83*85e6b674SGordon Ross #define ENUM_SLEN2_OFF 36
84*85e6b674SGordon Ross /* server name, length 14 vv ... */
85*85e6b674SGordon Ross 0x01, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
86*85e6b674SGordon Ross 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00 };
87*85e6b674SGordon Ross /* UNC server here, i.e.: "\\192.168.1.6" */
88*85e6b674SGordon Ross
89*85e6b674SGordon Ross static const uchar_t
90*85e6b674SGordon Ross srvsvc_enum2[] = {
91*85e6b674SGordon Ross 0x01, 0x00, 0x00, 0x00,
92*85e6b674SGordon Ross 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
93*85e6b674SGordon Ross 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94*85e6b674SGordon Ross 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 };
95*85e6b674SGordon Ross
96*85e6b674SGordon Ross static uchar_t sendbuf[1024];
97*85e6b674SGordon Ross static uchar_t recvbuf[4096];
98*85e6b674SGordon Ross static char *server;
99*85e6b674SGordon Ross
100*85e6b674SGordon Ross static int pipetest(struct smb_ctx *);
101*85e6b674SGordon Ross
102*85e6b674SGordon Ross static void
srvenum_usage(void)103*85e6b674SGordon Ross srvenum_usage(void)
104*85e6b674SGordon Ross {
105*85e6b674SGordon Ross printf("usage: srvenum [-d domain][-u user][-p passwd] server\n");
106*85e6b674SGordon Ross exit(1);
107*85e6b674SGordon Ross }
108*85e6b674SGordon Ross
109*85e6b674SGordon Ross int
main(int argc,char * argv[])110*85e6b674SGordon Ross main(int argc, char *argv[])
111*85e6b674SGordon Ross {
112*85e6b674SGordon Ross int c, error;
113*85e6b674SGordon Ross struct smb_ctx *ctx = NULL;
114*85e6b674SGordon Ross char *dom = NULL;
115*85e6b674SGordon Ross char *usr = NULL;
116*85e6b674SGordon Ross char *pw = NULL;
117*85e6b674SGordon Ross
118*85e6b674SGordon Ross while ((c = getopt(argc, argv, "vd:u:p:")) != -1) {
119*85e6b674SGordon Ross switch (c) {
120*85e6b674SGordon Ross case 'v':
121*85e6b674SGordon Ross smb_verbose = 1;
122*85e6b674SGordon Ross break;
123*85e6b674SGordon Ross
124*85e6b674SGordon Ross case 'd':
125*85e6b674SGordon Ross dom = optarg;
126*85e6b674SGordon Ross break;
127*85e6b674SGordon Ross case 'u':
128*85e6b674SGordon Ross usr = optarg;
129*85e6b674SGordon Ross break;
130*85e6b674SGordon Ross case 'p':
131*85e6b674SGordon Ross pw = optarg;
132*85e6b674SGordon Ross break;
133*85e6b674SGordon Ross case '?':
134*85e6b674SGordon Ross srvenum_usage();
135*85e6b674SGordon Ross break;
136*85e6b674SGordon Ross }
137*85e6b674SGordon Ross }
138*85e6b674SGordon Ross if (optind >= argc)
139*85e6b674SGordon Ross srvenum_usage();
140*85e6b674SGordon Ross server = argv[optind];
141*85e6b674SGordon Ross
142*85e6b674SGordon Ross if (pw != NULL && (dom == NULL || usr == NULL)) {
143*85e6b674SGordon Ross fprintf(stderr, "%s: -p arg requires -d dom -u usr\n",
144*85e6b674SGordon Ross argv[0]);
145*85e6b674SGordon Ross srvenum_usage();
146*85e6b674SGordon Ross }
147*85e6b674SGordon Ross
148*85e6b674SGordon Ross /*
149*85e6b674SGordon Ross * This section is intended to demonstrate how an
150*85e6b674SGordon Ross * RPC client library might use this interface.
151*85e6b674SGordon Ross */
152*85e6b674SGordon Ross error = smb_ctx_alloc(&ctx);
153*85e6b674SGordon Ross if (error) {
154*85e6b674SGordon Ross fprintf(stderr, "%s: smb_ctx_alloc failed\n", argv[0]);
155*85e6b674SGordon Ross goto out;
156*85e6b674SGordon Ross }
157*85e6b674SGordon Ross
158*85e6b674SGordon Ross /*
159*85e6b674SGordon Ross * Set server, share, domain, user
160*85e6b674SGordon Ross * (in the ctx handle).
161*85e6b674SGordon Ross */
162*85e6b674SGordon Ross smb_ctx_setfullserver(ctx, server);
163*85e6b674SGordon Ross smb_ctx_setshare(ctx, "IPC$", USE_IPC);
164*85e6b674SGordon Ross if (dom)
165*85e6b674SGordon Ross smb_ctx_setdomain(ctx, dom, B_TRUE);
166*85e6b674SGordon Ross if (usr)
167*85e6b674SGordon Ross smb_ctx_setuser(ctx, usr, B_TRUE);
168*85e6b674SGordon Ross if (pw)
169*85e6b674SGordon Ross smb_ctx_setpassword(ctx, pw, NULL);
170*85e6b674SGordon Ross
171*85e6b674SGordon Ross
172*85e6b674SGordon Ross /*
173*85e6b674SGordon Ross * If this code were in smbutil or mount_smbfs, it would
174*85e6b674SGordon Ross * get system and $HOME/.nsmbrc settings here, like this:
175*85e6b674SGordon Ross */
176*85e6b674SGordon Ross #if 0
177*85e6b674SGordon Ross error = smb_ctx_readrc(ctx);
178*85e6b674SGordon Ross if (error) {
179*85e6b674SGordon Ross fprintf(stderr, "%s: smb_ctx_readrc failed\n", argv[0]);
180*85e6b674SGordon Ross goto out;
181*85e6b674SGordon Ross }
182*85e6b674SGordon Ross #endif
183*85e6b674SGordon Ross
184*85e6b674SGordon Ross /*
185*85e6b674SGordon Ross * Resolve the server address,
186*85e6b674SGordon Ross * setup derived defaults.
187*85e6b674SGordon Ross */
188*85e6b674SGordon Ross error = smb_ctx_resolve(ctx);
189*85e6b674SGordon Ross if (error) {
190*85e6b674SGordon Ross fprintf(stderr, "%s: smb_ctx_resolve failed\n", argv[0]);
191*85e6b674SGordon Ross goto out;
192*85e6b674SGordon Ross }
193*85e6b674SGordon Ross
194*85e6b674SGordon Ross /*
195*85e6b674SGordon Ross * Get the session and tree.
196*85e6b674SGordon Ross */
197*85e6b674SGordon Ross error = smb_ctx_get_ssn(ctx);
198*85e6b674SGordon Ross if (error) {
199*85e6b674SGordon Ross fprintf(stderr, "//%s: login failed, error %d\n",
200*85e6b674SGordon Ross server, error);
201*85e6b674SGordon Ross goto out;
202*85e6b674SGordon Ross }
203*85e6b674SGordon Ross error = smb_ctx_get_tree(ctx);
204*85e6b674SGordon Ross if (error) {
205*85e6b674SGordon Ross fprintf(stderr, "//%s/%s: tree connect failed, %d\n",
206*85e6b674SGordon Ross server, "IPC$", error);
207*85e6b674SGordon Ross goto out;
208*85e6b674SGordon Ross }
209*85e6b674SGordon Ross
210*85e6b674SGordon Ross /*
211*85e6b674SGordon Ross * Do some named pipe I/O.
212*85e6b674SGordon Ross */
213*85e6b674SGordon Ross error = pipetest(ctx);
214*85e6b674SGordon Ross if (error) {
215*85e6b674SGordon Ross fprintf(stderr, "pipetest, %d\n", error);
216*85e6b674SGordon Ross goto out;
217*85e6b674SGordon Ross }
218*85e6b674SGordon Ross
219*85e6b674SGordon Ross out:
220*85e6b674SGordon Ross smb_ctx_free(ctx);
221*85e6b674SGordon Ross
222*85e6b674SGordon Ross return ((error) ? 1 : 0);
223*85e6b674SGordon Ross }
224*85e6b674SGordon Ross
225*85e6b674SGordon Ross static void
hexdump(const uchar_t * buf,int len)226*85e6b674SGordon Ross hexdump(const uchar_t *buf, int len) {
227*85e6b674SGordon Ross int idx;
228*85e6b674SGordon Ross char ascii[24];
229*85e6b674SGordon Ross char *pa = ascii;
230*85e6b674SGordon Ross
231*85e6b674SGordon Ross memset(ascii, '\0', sizeof (ascii));
232*85e6b674SGordon Ross
233*85e6b674SGordon Ross idx = 0;
234*85e6b674SGordon Ross while (len--) {
235*85e6b674SGordon Ross if ((idx & 15) == 0) {
236*85e6b674SGordon Ross printf("[%04X] ", idx);
237*85e6b674SGordon Ross pa = ascii;
238*85e6b674SGordon Ross }
239*85e6b674SGordon Ross if (*buf > ' ' && *buf <= '~')
240*85e6b674SGordon Ross *pa++ = *buf;
241*85e6b674SGordon Ross else
242*85e6b674SGordon Ross *pa++ = '.';
243*85e6b674SGordon Ross printf("%02x ", *buf++);
244*85e6b674SGordon Ross
245*85e6b674SGordon Ross idx++;
246*85e6b674SGordon Ross if ((idx & 7) == 0) {
247*85e6b674SGordon Ross *pa++ = ' ';
248*85e6b674SGordon Ross putchar(' ');
249*85e6b674SGordon Ross }
250*85e6b674SGordon Ross if ((idx & 15) == 0) {
251*85e6b674SGordon Ross *pa = '\0';
252*85e6b674SGordon Ross printf("%s\n", ascii);
253*85e6b674SGordon Ross }
254*85e6b674SGordon Ross }
255*85e6b674SGordon Ross
256*85e6b674SGordon Ross if ((idx & 15) != 0) {
257*85e6b674SGordon Ross *pa = '\0';
258*85e6b674SGordon Ross /* column align the last ascii row */
259*85e6b674SGordon Ross do {
260*85e6b674SGordon Ross printf(" ");
261*85e6b674SGordon Ross idx++;
262*85e6b674SGordon Ross if ((idx & 7) == 0)
263*85e6b674SGordon Ross putchar(' ');
264*85e6b674SGordon Ross } while ((idx & 15) != 0);
265*85e6b674SGordon Ross printf("%s\n", ascii);
266*85e6b674SGordon Ross }
267*85e6b674SGordon Ross }
268*85e6b674SGordon Ross
269*85e6b674SGordon Ross /*
270*85e6b674SGordon Ross * Put a unicode UNC server name, including the null.
271*85e6b674SGordon Ross * Quick-n-dirty, just for this test...
272*85e6b674SGordon Ross */
273*85e6b674SGordon Ross static int
put_uncserver(const char * s,uchar_t * buf)274*85e6b674SGordon Ross put_uncserver(const char *s, uchar_t *buf)
275*85e6b674SGordon Ross {
276*85e6b674SGordon Ross uchar_t *p = buf;
277*85e6b674SGordon Ross char c;
278*85e6b674SGordon Ross
279*85e6b674SGordon Ross *p++ = '\\'; *p++ = '\0';
280*85e6b674SGordon Ross *p++ = '\\'; *p++ = '\0';
281*85e6b674SGordon Ross
282*85e6b674SGordon Ross do {
283*85e6b674SGordon Ross c = *s++;
284*85e6b674SGordon Ross if (c == '/')
285*85e6b674SGordon Ross c = '\\';
286*85e6b674SGordon Ross *p++ = c;
287*85e6b674SGordon Ross *p++ = '\0';
288*85e6b674SGordon Ross
289*85e6b674SGordon Ross } while (c != 0);
290*85e6b674SGordon Ross
291*85e6b674SGordon Ross return (p - buf);
292*85e6b674SGordon Ross }
293*85e6b674SGordon Ross
294*85e6b674SGordon Ross /*
295*85e6b674SGordon Ross * Send the bind and read the ack.
296*85e6b674SGordon Ross * This tests smb_fh_xactnp.
297*85e6b674SGordon Ross */
298*85e6b674SGordon Ross static int
do_bind(int fid)299*85e6b674SGordon Ross do_bind(int fid)
300*85e6b674SGordon Ross {
301*85e6b674SGordon Ross int err, len, more;
302*85e6b674SGordon Ross
303*85e6b674SGordon Ross more = 0;
304*85e6b674SGordon Ross len = sizeof (recvbuf);
305*85e6b674SGordon Ross err = smb_fh_xactnp(fid,
306*85e6b674SGordon Ross sizeof (srvsvc_bind), (char *)srvsvc_bind,
307*85e6b674SGordon Ross &len, (char *)recvbuf, &more);
308*85e6b674SGordon Ross if (err) {
309*85e6b674SGordon Ross printf("xact bind, err=%d\n", err);
310*85e6b674SGordon Ross return (err);
311*85e6b674SGordon Ross }
312*85e6b674SGordon Ross if (smb_verbose) {
313*85e6b674SGordon Ross printf("bind ack, len=%d\n", len);
314*85e6b674SGordon Ross hexdump(recvbuf, len);
315*85e6b674SGordon Ross }
316*85e6b674SGordon Ross if (more > 0) {
317*85e6b674SGordon Ross if (more > sizeof (recvbuf)) {
318*85e6b674SGordon Ross printf("bogus more=%d\n", more);
319*85e6b674SGordon Ross more = sizeof (recvbuf);
320*85e6b674SGordon Ross }
321*85e6b674SGordon Ross len = smb_fh_read(fid, 0,
322*85e6b674SGordon Ross more, (char *)recvbuf);
323*85e6b674SGordon Ross if (len == -1) {
324*85e6b674SGordon Ross err = EIO;
325*85e6b674SGordon Ross printf("read enum resp, err=%d\n", err);
326*85e6b674SGordon Ross return (err);
327*85e6b674SGordon Ross }
328*85e6b674SGordon Ross if (smb_verbose) {
329*85e6b674SGordon Ross printf("bind ack (more), len=%d\n", len);
330*85e6b674SGordon Ross hexdump(recvbuf, len);
331*85e6b674SGordon Ross }
332*85e6b674SGordon Ross }
333*85e6b674SGordon Ross
334*85e6b674SGordon Ross return (0);
335*85e6b674SGordon Ross }
336*85e6b674SGordon Ross
337*85e6b674SGordon Ross static int
do_enum(int fid)338*85e6b674SGordon Ross do_enum(int fid)
339*85e6b674SGordon Ross {
340*85e6b674SGordon Ross int err, len, rlen, wlen;
341*85e6b674SGordon Ross uchar_t *p;
342*85e6b674SGordon Ross
343*85e6b674SGordon Ross /*
344*85e6b674SGordon Ross * Build the enum request - three parts.
345*85e6b674SGordon Ross * See above: srvsvc_enum1, srvsvc_enum2
346*85e6b674SGordon Ross *
347*85e6b674SGordon Ross * First part: RPC header, etc.
348*85e6b674SGordon Ross */
349*85e6b674SGordon Ross p = sendbuf;
350*85e6b674SGordon Ross len = sizeof (srvsvc_enum1); /* 40 */
351*85e6b674SGordon Ross memcpy(p, srvsvc_enum1, len);
352*85e6b674SGordon Ross p += len;
353*85e6b674SGordon Ross
354*85e6b674SGordon Ross /* Second part: UNC server name */
355*85e6b674SGordon Ross len = put_uncserver(server, p);
356*85e6b674SGordon Ross p += len;
357*85e6b674SGordon Ross sendbuf[ENUM_SLEN1_OFF] = len / 2;
358*85e6b674SGordon Ross sendbuf[ENUM_SLEN2_OFF] = len / 2;
359*85e6b674SGordon Ross
360*85e6b674SGordon Ross /* Third part: level, etc. (align4) */
361*85e6b674SGordon Ross for (len = (p - sendbuf) & 3; len; len--)
362*85e6b674SGordon Ross *p++ = '\0';
363*85e6b674SGordon Ross len = sizeof (srvsvc_enum2); /* 28 */
364*85e6b674SGordon Ross memcpy(p, srvsvc_enum2, len);
365*85e6b674SGordon Ross p += len;
366*85e6b674SGordon Ross
367*85e6b674SGordon Ross /*
368*85e6b674SGordon Ross * Compute total length, and fixup RPC header.
369*85e6b674SGordon Ross */
370*85e6b674SGordon Ross len = p - sendbuf;
371*85e6b674SGordon Ross sendbuf[ENUM_RPCLEN_OFF] = len;
372*85e6b674SGordon Ross
373*85e6b674SGordon Ross /*
374*85e6b674SGordon Ross * Send the enum request, read the response.
375*85e6b674SGordon Ross * This tests smb_fh_write, smb_fh_read.
376*85e6b674SGordon Ross */
377*85e6b674SGordon Ross wlen = smb_fh_write(fid, 0, len, (char *)sendbuf);
378*85e6b674SGordon Ross if (wlen == -1) {
379*85e6b674SGordon Ross err = errno;
380*85e6b674SGordon Ross printf("write enum req, err=%d\n", err);
381*85e6b674SGordon Ross return (err);
382*85e6b674SGordon Ross }
383*85e6b674SGordon Ross if (wlen != len) {
384*85e6b674SGordon Ross printf("write enum req, short write %d\n", wlen);
385*85e6b674SGordon Ross return (EIO);
386*85e6b674SGordon Ross }
387*85e6b674SGordon Ross
388*85e6b674SGordon Ross rlen = smb_fh_read(fid, 0,
389*85e6b674SGordon Ross sizeof (recvbuf), (char *)recvbuf);
390*85e6b674SGordon Ross if (rlen == -1) {
391*85e6b674SGordon Ross err = errno;
392*85e6b674SGordon Ross printf("read enum resp, err=%d\n", err);
393*85e6b674SGordon Ross return (err);
394*85e6b674SGordon Ross }
395*85e6b674SGordon Ross
396*85e6b674SGordon Ross /* Just dump the response data. */
397*85e6b674SGordon Ross printf("enum recv, len=%d\n", rlen);
398*85e6b674SGordon Ross hexdump(recvbuf, rlen);
399*85e6b674SGordon Ross
400*85e6b674SGordon Ross return (0);
401*85e6b674SGordon Ross }
402*85e6b674SGordon Ross
403*85e6b674SGordon Ross static int
pipetest(struct smb_ctx * ctx)404*85e6b674SGordon Ross pipetest(struct smb_ctx *ctx)
405*85e6b674SGordon Ross {
406*85e6b674SGordon Ross static char path[] = "/srvsvc";
407*85e6b674SGordon Ross static uchar_t key[16];
408*85e6b674SGordon Ross int err, fd;
409*85e6b674SGordon Ross
410*85e6b674SGordon Ross printf("open pipe: %s\n", path);
411*85e6b674SGordon Ross fd = smb_fh_open(ctx, path, O_RDWR);
412*85e6b674SGordon Ross if (fd < 0) {
413*85e6b674SGordon Ross perror(path);
414*85e6b674SGordon Ross return (errno);
415*85e6b674SGordon Ross }
416*85e6b674SGordon Ross
417*85e6b674SGordon Ross /* Test this too. */
418*85e6b674SGordon Ross err = smb_fh_getssnkey(fd, key, sizeof (key));
419*85e6b674SGordon Ross if (err) {
420*85e6b674SGordon Ross printf("getssnkey: %d\n", err);
421*85e6b674SGordon Ross goto out;
422*85e6b674SGordon Ross }
423*85e6b674SGordon Ross
424*85e6b674SGordon Ross err = do_bind(fd);
425*85e6b674SGordon Ross if (err) {
426*85e6b674SGordon Ross printf("do_bind: %d\n", err);
427*85e6b674SGordon Ross goto out;
428*85e6b674SGordon Ross }
429*85e6b674SGordon Ross err = do_enum(fd);
430*85e6b674SGordon Ross if (err)
431*85e6b674SGordon Ross printf("do_enum: %d\n", err);
432*85e6b674SGordon Ross
433*85e6b674SGordon Ross out:
434*85e6b674SGordon Ross smb_fh_close(fd);
435*85e6b674SGordon Ross return (0);
436*85e6b674SGordon Ross }
437