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 (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 23 * Copyright 2011-2021 Tintri by DDN, Inc. All rights reserved. 24 * Copyright 2022 RackTop Systems, Inc. 25 */ 26 27 /* 28 * This module provides the interface to NDR RPC. 29 */ 30 31 #include <sys/stat.h> 32 #include <sys/uio.h> 33 #include <sys/ksynch.h> 34 #include <sys/stropts.h> 35 #include <sys/socket.h> 36 #include <sys/filio.h> 37 #include <smbsrv/smb_kproto.h> 38 #include <smbsrv/smb_xdr.h> 39 #include <smb/winioctl.h> 40 41 static uint32_t smb_opipe_wait(smb_request_t *, smb_fsctl_t *); 42 43 /* 44 * Allocate a new opipe and return it, or NULL, in which case 45 * the caller will report "internal error". 46 */ 47 static smb_opipe_t * 48 smb_opipe_alloc(smb_request_t *sr) 49 { 50 smb_server_t *sv = sr->sr_server; 51 smb_opipe_t *opipe; 52 ksocket_t sock; 53 54 if (ksocket_socket(&sock, AF_UNIX, SOCK_STREAM, 0, 55 KSOCKET_SLEEP, sr->user_cr) != 0) 56 return (NULL); 57 58 opipe = kmem_cache_alloc(smb_cache_opipe, KM_SLEEP); 59 60 bzero(opipe, sizeof (smb_opipe_t)); 61 mutex_init(&opipe->p_mutex, NULL, MUTEX_DEFAULT, NULL); 62 cv_init(&opipe->p_cv, NULL, CV_DEFAULT, NULL); 63 opipe->p_magic = SMB_OPIPE_MAGIC; 64 opipe->p_server = sv; 65 opipe->p_refcnt = 1; 66 opipe->p_socket = sock; 67 68 return (opipe); 69 } 70 71 /* 72 * Destroy an opipe. This is normally called from smb_ofile_delete 73 * when the ofile has no more references and is about to be free'd. 74 * This is also called here in error handling code paths, before 75 * the opipe is installed under an ofile. 76 */ 77 void 78 smb_opipe_dealloc(smb_opipe_t *opipe) 79 { 80 smb_server_t *sv; 81 82 SMB_OPIPE_VALID(opipe); 83 sv = opipe->p_server; 84 SMB_SERVER_VALID(sv); 85 86 /* 87 * This is called in the error path when opening, 88 * in which case we close the socket here. 89 */ 90 if (opipe->p_socket != NULL) 91 (void) ksocket_close(opipe->p_socket, zone_kcred()); 92 93 opipe->p_magic = (uint32_t)~SMB_OPIPE_MAGIC; 94 cv_destroy(&opipe->p_cv); 95 mutex_destroy(&opipe->p_mutex); 96 97 kmem_cache_free(smb_cache_opipe, opipe); 98 } 99 100 /* 101 * Unblock a request that might be blocked reading some 102 * pipe (AF_UNIX socket). We don't have an easy way to 103 * interrupt just the thread servicing this request, so 104 * we shutdown(3socket) the socket, waking all readers. 105 * That's a bit heavy-handed, making the socket unusable 106 * after this, so we do this only when disconnecting a 107 * session (i.e. stopping the SMB service), and not when 108 * handling an SMB2_cancel or SMB_nt_cancel request. 109 */ 110 static void 111 smb_opipe_cancel(smb_request_t *sr) 112 { 113 ksocket_t so; 114 115 switch (sr->session->s_state) { 116 case SMB_SESSION_STATE_DISCONNECTED: 117 case SMB_SESSION_STATE_TERMINATED: 118 if ((so = sr->cancel_arg2) != NULL) 119 (void) ksocket_shutdown(so, SHUT_RDWR, sr->user_cr); 120 break; 121 } 122 } 123 124 /* 125 * Helper for open: build pipe name and connect. 126 */ 127 static int 128 smb_opipe_connect(smb_request_t *sr, smb_opipe_t *opipe) 129 { 130 struct sockaddr_un saddr; 131 smb_arg_open_t *op = &sr->sr_open; 132 const char *name; 133 int rc; 134 135 name = op->fqi.fq_path.pn_path; 136 name += strspn(name, "\\"); 137 if (smb_strcasecmp(name, "PIPE", 4) == 0) { 138 name += 4; 139 name += strspn(name, "\\"); 140 } 141 (void) strlcpy(opipe->p_name, name, SMB_OPIPE_MAXNAME); 142 (void) smb_strlwr(opipe->p_name); 143 144 bzero(&saddr, sizeof (saddr)); 145 saddr.sun_family = AF_UNIX; 146 (void) snprintf(saddr.sun_path, sizeof (saddr.sun_path), 147 "%s/%s", SMB_PIPE_DIR, opipe->p_name); 148 rc = ksocket_connect(opipe->p_socket, (struct sockaddr *)&saddr, 149 sizeof (saddr), sr->user_cr); 150 151 return (rc); 152 } 153 154 static int 155 smb_opipe_exists(char *name) 156 { 157 struct sockaddr_un saddr; 158 vnode_t *vp; /* Underlying filesystem vnode */ 159 int err; 160 161 bzero(&saddr, sizeof (saddr)); 162 saddr.sun_family = AF_UNIX; 163 (void) snprintf(saddr.sun_path, sizeof (saddr.sun_path), 164 "%s/%s", SMB_PIPE_DIR, name); 165 166 err = lookupname(saddr.sun_path, UIO_SYSSPACE, FOLLOW, NULLVPP, &vp); 167 if (err == 0) { 168 VN_RELE(vp); /* release hold from lookup */ 169 } 170 171 return (err); 172 } 173 174 175 /* 176 * Helper for open: encode and send the user info. 177 * 178 * We send information about this client + user to the 179 * pipe service so it can use it for access checks. 180 * The service MAY deny the open based on this info, 181 * (i.e. anonymous session trying to open a pipe that 182 * requires authentication) in which case we will read 183 * an error status from the service and return that. 184 */ 185 static void 186 smb_opipe_send_userinfo(smb_request_t *sr, smb_opipe_t *opipe, 187 smb_error_t *errp) 188 { 189 XDR xdrs; 190 smb_netuserinfo_t nui; 191 smb_pipehdr_t phdr; 192 char *buf; 193 uint32_t buflen; 194 uint32_t status; 195 size_t iocnt = 0; 196 int rc; 197 198 /* 199 * Any errors building the XDR message etc. 200 */ 201 errp->status = NT_STATUS_INTERNAL_ERROR; 202 203 smb_user_netinfo_init(sr->uid_user, &nui); 204 phdr.ph_magic = SMB_PIPE_HDR_MAGIC; 205 phdr.ph_uilen = xdr_sizeof(smb_netuserinfo_xdr, &nui); 206 207 buflen = sizeof (phdr) + phdr.ph_uilen; 208 buf = kmem_alloc(buflen, KM_SLEEP); 209 210 bcopy(&phdr, buf, sizeof (phdr)); 211 xdrmem_create(&xdrs, buf + sizeof (phdr), 212 buflen - (sizeof (phdr)), XDR_ENCODE); 213 if (!smb_netuserinfo_xdr(&xdrs, &nui)) 214 goto out; 215 216 /* 217 * Prepare for cancellable send/recv. 218 */ 219 mutex_enter(&sr->sr_mutex); 220 if (sr->sr_state != SMB_REQ_STATE_ACTIVE) { 221 mutex_exit(&sr->sr_mutex); 222 errp->status = NT_STATUS_CANCELLED; 223 goto out; 224 } 225 sr->sr_state = SMB_REQ_STATE_WAITING_PIPE; 226 sr->cancel_method = smb_opipe_cancel; 227 sr->cancel_arg2 = opipe->p_socket; 228 mutex_exit(&sr->sr_mutex); 229 230 rc = ksocket_send(opipe->p_socket, buf, buflen, 0, 231 &iocnt, sr->user_cr); 232 if (rc == 0 && iocnt != buflen) 233 rc = EIO; 234 if (rc == 0) 235 rc = ksocket_recv(opipe->p_socket, &status, sizeof (status), 236 0, &iocnt, sr->user_cr); 237 if (rc == 0 && iocnt != sizeof (status)) 238 rc = EIO; 239 240 /* 241 * Did the send/recv. complete or was it cancelled? 242 */ 243 mutex_enter(&sr->sr_mutex); 244 switch_state: 245 switch (sr->sr_state) { 246 case SMB_REQ_STATE_WAITING_PIPE: 247 /* Normal wakeup. Keep rc from above. */ 248 sr->sr_state = SMB_REQ_STATE_ACTIVE; 249 break; 250 case SMB_REQ_STATE_CANCEL_PENDING: 251 /* cancel_method running. wait. */ 252 cv_wait(&sr->sr_st_cv, &sr->sr_mutex); 253 goto switch_state; 254 case SMB_REQ_STATE_CANCELLED: 255 rc = EINTR; 256 break; 257 default: 258 /* keep rc from above */ 259 break; 260 } 261 sr->cancel_method = NULL; 262 sr->cancel_arg2 = NULL; 263 mutex_exit(&sr->sr_mutex); 264 265 /* 266 * Return the status we read from the pipe service, 267 * normally NT_STATUS_SUCCESS, but could be something 268 * else like NT_STATUS_ACCESS_DENIED. 269 */ 270 switch (rc) { 271 case 0: 272 errp->status = status; 273 break; 274 case EINTR: 275 errp->status = NT_STATUS_CANCELLED; 276 break; 277 /* 278 * If we fail sending the netuserinfo or recv'ing the 279 * status reponse, we have probably run into the limit 280 * on the number of open pipes. That's this status: 281 */ 282 default: 283 errp->status = NT_STATUS_PIPE_NOT_AVAILABLE; 284 break; 285 } 286 287 out: 288 xdr_destroy(&xdrs); 289 kmem_free(buf, buflen); 290 smb_user_netinfo_fini(&nui); 291 } 292 293 /* 294 * smb_opipe_open 295 * 296 * Open an RPC named pipe. This routine should be called if 297 * a file open is requested on a share of type STYPE_IPC. 298 * If we recognize the pipe, we setup a new ofile. 299 * 300 * Returns 0 on success, Otherwise an NT status code. 301 */ 302 int 303 smb_opipe_open(smb_request_t *sr, smb_ofile_t *ofile) 304 { 305 smb_arg_open_t *op = &sr->sr_open; 306 smb_attr_t *ap = &op->fqi.fq_fattr; 307 smb_opipe_t *opipe; 308 smb_error_t err; 309 310 opipe = smb_opipe_alloc(sr); 311 if (opipe == NULL) 312 return (NT_STATUS_INTERNAL_ERROR); 313 314 if (smb_opipe_connect(sr, opipe) != 0) { 315 smb_opipe_dealloc(opipe); 316 return (NT_STATUS_OBJECT_NAME_NOT_FOUND); 317 } 318 319 smb_opipe_send_userinfo(sr, opipe, &err); 320 if (err.status != 0) { 321 smb_opipe_dealloc(opipe); 322 return (err.status); 323 } 324 325 /* 326 * We might have blocked in smb_opipe_connect long enough so 327 * a tree disconnect might have happened. In that case, we 328 * would be adding an ofile to a tree that's disconnecting, 329 * which would interfere with tear-down. 330 */ 331 if (!smb_tree_is_connected(sr->tid_tree)) { 332 smb_opipe_dealloc(opipe); 333 return (NT_STATUS_NETWORK_NAME_DELETED); 334 } 335 336 /* 337 * Note: The new opipe is given to smb_ofile_open 338 * via op->pipe 339 */ 340 op->pipe = opipe; 341 smb_ofile_open(sr, op, ofile); 342 op->pipe = NULL; 343 344 /* An "up" pointer, for debug. */ 345 opipe->p_ofile = ofile; 346 347 /* 348 * Caller expects attributes in op->fqi 349 */ 350 (void) smb_opipe_getattr(ofile, &op->fqi.fq_fattr); 351 352 op->dsize = 0; 353 op->dattr = ap->sa_dosattr; 354 op->fileid = ap->sa_vattr.va_nodeid; 355 op->ftype = SMB_FTYPE_MESG_PIPE; 356 op->action_taken = SMB_OACT_OPLOCK | SMB_OACT_OPENED; 357 op->devstate = SMB_PIPE_READMODE_MESSAGE 358 | SMB_PIPE_TYPE_MESSAGE 359 | SMB_PIPE_UNLIMITED_INSTANCES; /* 0x05ff */ 360 361 sr->smb_fid = ofile->f_fid; 362 sr->fid_ofile = ofile; 363 364 return (NT_STATUS_SUCCESS); 365 } 366 367 /* 368 * smb_opipe_close 369 * 370 * Called by smb_ofile_close for pipes. 371 * 372 * Note: ksocket_close may block while waiting for 373 * any I/O threads with a hold to get out. 374 */ 375 void 376 smb_opipe_close(smb_ofile_t *of) 377 { 378 smb_opipe_t *opipe; 379 ksocket_t sock; 380 381 ASSERT(of->f_state == SMB_OFILE_STATE_CLOSING); 382 ASSERT(of->f_ftype == SMB_FTYPE_MESG_PIPE); 383 opipe = of->f_pipe; 384 SMB_OPIPE_VALID(opipe); 385 386 mutex_enter(&opipe->p_mutex); 387 sock = opipe->p_socket; 388 opipe->p_socket = NULL; 389 mutex_exit(&opipe->p_mutex); 390 391 (void) ksocket_shutdown(sock, SHUT_RDWR, of->f_cr); 392 (void) ksocket_close(sock, of->f_cr); 393 } 394 395 /* 396 * smb_opipe_write 397 * 398 * Write RPC request data to the pipe. The client should call smb_opipe_read 399 * to complete the exchange and obtain the RPC response. 400 * 401 * Returns 0 on success or an errno on failure. 402 */ 403 int 404 smb_opipe_write(smb_request_t *sr, struct uio *uio) 405 { 406 struct nmsghdr msghdr; 407 smb_ofile_t *ofile; 408 smb_opipe_t *opipe; 409 ksocket_t sock; 410 size_t sent = 0; 411 int rc = 0; 412 413 ofile = sr->fid_ofile; 414 ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE); 415 opipe = ofile->f_pipe; 416 SMB_OPIPE_VALID(opipe); 417 418 mutex_enter(&opipe->p_mutex); 419 sock = opipe->p_socket; 420 if (sock != NULL) 421 ksocket_hold(sock); 422 mutex_exit(&opipe->p_mutex); 423 if (sock == NULL) 424 return (EBADF); 425 426 bzero(&msghdr, sizeof (msghdr)); 427 msghdr.msg_iov = uio->uio_iov; 428 msghdr.msg_iovlen = uio->uio_iovcnt; 429 430 /* 431 * This should block until we've sent it all, 432 * or given up due to errors (pipe closed). 433 */ 434 while (uio->uio_resid > 0) { 435 rc = ksocket_sendmsg(sock, &msghdr, 0, &sent, ofile->f_cr); 436 if (rc != 0) 437 break; 438 uio->uio_resid -= sent; 439 } 440 441 ksocket_rele(sock); 442 443 return (rc); 444 } 445 446 /* 447 * smb_opipe_read 448 * 449 * This interface may be called from smb_opipe_transact (write, read) 450 * or from smb_read / smb2_read to get the rest of an RPC response. 451 * The response data (and length) are returned via the uio. 452 */ 453 int 454 smb_opipe_read(smb_request_t *sr, struct uio *uio) 455 { 456 struct nmsghdr msghdr; 457 smb_ofile_t *ofile; 458 smb_opipe_t *opipe; 459 ksocket_t sock; 460 size_t recvcnt = 0; 461 int rc; 462 463 ofile = sr->fid_ofile; 464 ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE); 465 opipe = ofile->f_pipe; 466 SMB_OPIPE_VALID(opipe); 467 468 mutex_enter(&opipe->p_mutex); 469 sock = opipe->p_socket; 470 if (sock != NULL) 471 ksocket_hold(sock); 472 mutex_exit(&opipe->p_mutex); 473 if (sock == NULL) 474 return (EBADF); 475 476 /* 477 * Prepare for cancellable recvmsg. 478 */ 479 mutex_enter(&sr->sr_mutex); 480 if (sr->sr_state != SMB_REQ_STATE_ACTIVE) { 481 mutex_exit(&sr->sr_mutex); 482 rc = EINTR; 483 goto out; 484 } 485 sr->sr_state = SMB_REQ_STATE_WAITING_PIPE; 486 sr->cancel_method = smb_opipe_cancel; 487 sr->cancel_arg2 = sock; 488 mutex_exit(&sr->sr_mutex); 489 490 /* 491 * This should block only if there's no data. 492 * A single call to recvmsg does just that. 493 * (Intentionaly no recv loop here.) 494 */ 495 bzero(&msghdr, sizeof (msghdr)); 496 msghdr.msg_iov = uio->uio_iov; 497 msghdr.msg_iovlen = uio->uio_iovcnt; 498 rc = ksocket_recvmsg(sock, &msghdr, 0, 499 &recvcnt, ofile->f_cr); 500 501 /* 502 * Did the recvmsg complete or was it cancelled? 503 */ 504 mutex_enter(&sr->sr_mutex); 505 switch_state: 506 switch (sr->sr_state) { 507 case SMB_REQ_STATE_WAITING_PIPE: 508 /* Normal wakeup. Keep rc from above. */ 509 sr->sr_state = SMB_REQ_STATE_ACTIVE; 510 break; 511 case SMB_REQ_STATE_CANCEL_PENDING: 512 /* cancel_method running. wait. */ 513 cv_wait(&sr->sr_st_cv, &sr->sr_mutex); 514 goto switch_state; 515 case SMB_REQ_STATE_CANCELLED: 516 rc = EINTR; 517 break; 518 default: 519 /* keep rc from above */ 520 break; 521 } 522 sr->cancel_method = NULL; 523 sr->cancel_arg2 = NULL; 524 mutex_exit(&sr->sr_mutex); 525 526 if (rc != 0) 527 goto out; 528 529 if (recvcnt == 0) { 530 /* Other side closed. */ 531 rc = EPIPE; 532 goto out; 533 } 534 uio->uio_resid -= recvcnt; 535 536 out: 537 ksocket_rele(sock); 538 539 return (rc); 540 } 541 542 int 543 smb_opipe_ioctl(smb_request_t *sr, int cmd, void *arg, int *rvalp) 544 { 545 smb_ofile_t *ofile; 546 smb_opipe_t *opipe; 547 ksocket_t sock; 548 int rc; 549 550 ofile = sr->fid_ofile; 551 ASSERT(ofile->f_ftype == SMB_FTYPE_MESG_PIPE); 552 opipe = ofile->f_pipe; 553 SMB_OPIPE_VALID(opipe); 554 555 mutex_enter(&opipe->p_mutex); 556 sock = opipe->p_socket; 557 if (sock != NULL) 558 ksocket_hold(sock); 559 mutex_exit(&opipe->p_mutex); 560 if (sock == NULL) 561 return (EBADF); 562 563 rc = ksocket_ioctl(sock, cmd, (intptr_t)arg, rvalp, ofile->f_cr); 564 565 ksocket_rele(sock); 566 567 return (rc); 568 } 569 570 /* 571 * Get the smb_attr_t for a named pipe. 572 * Caller has already cleared to zero. 573 */ 574 int 575 smb_opipe_getattr(smb_ofile_t *of, smb_attr_t *ap) 576 { 577 578 if (of->f_pipe == NULL) 579 return (EINVAL); 580 581 ap->sa_vattr.va_type = VFIFO; 582 ap->sa_vattr.va_nlink = 1; 583 ap->sa_vattr.va_nodeid = (uintptr_t)of->f_pipe; 584 ap->sa_dosattr = FILE_ATTRIBUTE_NORMAL; 585 ap->sa_allocsz = SMB_PIPE_MAX_MSGSIZE; 586 587 return (0); 588 } 589 590 int 591 smb_opipe_getname(smb_ofile_t *of, char *buf, size_t buflen) 592 { 593 smb_opipe_t *opipe; 594 595 if ((opipe = of->f_pipe) == NULL) 596 return (EINVAL); 597 598 (void) snprintf(buf, buflen, "\\%s", opipe->p_name); 599 return (0); 600 } 601 602 /* 603 * Handle device type FILE_DEVICE_NAMED_PIPE 604 * for smb2_ioctl 605 */ 606 /* ARGSUSED */ 607 uint32_t 608 smb_opipe_fsctl(smb_request_t *sr, smb_fsctl_t *fsctl) 609 { 610 uint32_t status; 611 612 if (!STYPE_ISIPC(sr->tid_tree->t_res_type)) 613 return (NT_STATUS_INVALID_DEVICE_REQUEST); 614 615 switch (fsctl->CtlCode) { 616 case FSCTL_PIPE_TRANSCEIVE: 617 status = smb_opipe_transceive(sr, fsctl); 618 break; 619 620 case FSCTL_PIPE_PEEK: 621 status = NT_STATUS_INVALID_DEVICE_REQUEST; 622 break; 623 624 case FSCTL_PIPE_WAIT: 625 status = smb_opipe_wait(sr, fsctl); 626 break; 627 628 default: 629 ASSERT(!"CtlCode"); 630 status = NT_STATUS_INTERNAL_ERROR; 631 break; 632 } 633 634 return (status); 635 } 636 637 uint32_t 638 smb_opipe_transceive(smb_request_t *sr, smb_fsctl_t *fsctl) 639 { 640 smb_vdb_t *vdb; 641 smb_ofile_t *ofile; 642 struct mbuf *mb; 643 uint32_t status; 644 int len, rc; 645 646 /* 647 * Caller checked that this is the IPC$ share, 648 * and that this call has a valid open handle. 649 * Just check the type. 650 */ 651 ofile = sr->fid_ofile; 652 if (ofile->f_ftype != SMB_FTYPE_MESG_PIPE) 653 return (NT_STATUS_INVALID_HANDLE); 654 655 /* 656 * The VDB is a bit large. Allocate. 657 * This is automatically free'd with the SR 658 */ 659 vdb = smb_srm_zalloc(sr, sizeof (*vdb)); 660 rc = smb_mbc_decodef(fsctl->in_mbc, "#B", 661 fsctl->InputCount, vdb); 662 if (rc != 0) { 663 /* Not enough data sent. */ 664 return (NT_STATUS_INVALID_PARAMETER); 665 } 666 667 rc = smb_opipe_write(sr, &vdb->vdb_uio); 668 if (rc != 0) 669 return (smb_errno2status(rc)); 670 671 vdb->vdb_tag = 0; 672 vdb->vdb_uio.uio_iov = &vdb->vdb_iovec[0]; 673 vdb->vdb_uio.uio_iovcnt = MAX_IOVEC; 674 vdb->vdb_uio.uio_segflg = UIO_SYSSPACE; 675 vdb->vdb_uio.uio_extflg = UIO_COPY_DEFAULT; 676 vdb->vdb_uio.uio_loffset = (offset_t)0; 677 vdb->vdb_uio.uio_resid = fsctl->MaxOutputResp; 678 mb = smb_mbuf_allocate(&vdb->vdb_uio); 679 680 rc = smb_opipe_read(sr, &vdb->vdb_uio); 681 if (rc != 0) { 682 m_freem(mb); 683 return (smb_errno2status(rc)); 684 } 685 686 len = fsctl->MaxOutputResp - vdb->vdb_uio.uio_resid; 687 smb_mbuf_trim(mb, len); 688 MBC_ATTACH_MBUF(fsctl->out_mbc, mb); 689 690 /* 691 * If the output buffer holds a partial pipe message, 692 * we're supposed to return NT_STATUS_BUFFER_OVERFLOW. 693 * As we don't have message boundary markers, the best 694 * we can do is return that status when we have ALL of: 695 * Output buffer was < SMB_PIPE_MAX_MSGSIZE 696 * We filled the output buffer (resid==0) 697 * There's more data (ioctl FIONREAD) 698 */ 699 status = NT_STATUS_SUCCESS; 700 if (fsctl->MaxOutputResp < SMB_PIPE_MAX_MSGSIZE && 701 vdb->vdb_uio.uio_resid == 0) { 702 int nread = 0, trval; 703 rc = smb_opipe_ioctl(sr, FIONREAD, &nread, &trval); 704 if (rc == 0 && nread != 0) 705 status = NT_STATUS_BUFFER_OVERFLOW; 706 } 707 708 return (status); 709 } 710 711 static uint32_t 712 smb_opipe_wait(smb_request_t *sr, smb_fsctl_t *fsctl) 713 { 714 char *name; 715 uint64_t timeout; 716 uint32_t namelen; 717 int rc; 718 uint8_t tflag; 719 720 rc = smb_mbc_decodef(fsctl->in_mbc, "qlb.", 721 &timeout, /* q */ 722 &namelen, /* l */ 723 &tflag); /* b */ 724 if (rc != 0) 725 return (NT_STATUS_INVALID_PARAMETER); 726 rc = smb_mbc_decodef(fsctl->in_mbc, "%#U", 727 sr, /* % */ 728 namelen, /* # */ 729 &name); /* U */ 730 if (rc != 0) 731 return (NT_STATUS_INVALID_PARAMETER); 732 733 rc = smb_opipe_exists(name); 734 if (rc != 0) 735 return (NT_STATUS_OBJECT_NAME_NOT_FOUND); 736 737 /* 738 * At this point we know the pipe exists. 739 * 740 * If the tflag is set, we're supposed to wait for up to 741 * timeout (100s of milliseconds) for a pipe "instance" 742 * to become "available" (so pipe open would work). 743 * However, this implementation has no need to wait, 744 * so just take a short delay instead. 745 */ 746 if (tflag != 0) { 747 clock_t ticks = MSEC_TO_TICK(timeout * 100); 748 if (ticks > MSEC_TO_TICK(100)) 749 ticks = MSEC_TO_TICK(100); 750 delay(ticks); 751 } 752 753 return (0); 754 } 755