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 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 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 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 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 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 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 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