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