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